如果要动态改变字段名,即提供类变量名作为值,找到匹配给定的变量名和最后更改值该字段场,有几种方法:简单的一个是使用模式匹配来检查字段值并自己更改实例值并返回实例。然而,如果你需要处理在你的类中定义的每个字段,并且在你有很多字段的情况下,它可能非常麻烦,这可能非常麻烦。因此,你需要一些通用的方法来解决这个问题。
另一种方法是使用阶反射。 Scala反射是为此而设计的,即在运行时像你的情况一样修改你的代码,并以更通用的方式。以下是一个代码片段,用于更改给定字段名称的实例值。
case class Features(
// star about
var one_star: String = "0",
var two_star: String = "0",
var three_star: String = "0",
var four_star: String = "0"
// other about
) {
def copyInstance(variableName: String, value: String): Features = {
// 1. Initialize Features instance
val instance = Features()
// 2. Import scala reflection api.
import scala.reflect.runtime.{universe => ru}
// 3. Get the mirror of instance of Features class.
// Mirror will reflect to instance of Features case class, and we will use this instance mirror to modify its fields value.
val instanceMirror = ru.runtimeMirror(instance.getClass.getClassLoader).reflect(instance)
// 4. Now, Get the field whose value need to be changed - i.e. name you provide - variableName.
val field = ru.typeOf[Features].decl(ru.TermName(variableName)).asTerm
// 5. Get the mirror for that field so that we can read and write to this field.
val fieldMirror = instanceMirror.reflectField(field)
// 6. Finally, set the value to this field.
fieldMirror.set(value)
// 7. Return the changed instance.
instance
}
}
val features = Features()
val changedFeatures = features.copyInstance("one_star", "changed")
println(features)
println(changedFeatures)
//Result
Features(0,0,0,0)
Features(changed,0,0,0)
另外请注意,您可能需要处理Exception
为在提供无效的变量名和值的情况。另外,如果您的案例类包含> 22个字段参数,则案例类的某些功能不可用。
非常感谢您的长期回答,这非常符合我的要求。我搜索,经过斯卡拉2.11 – xuhai
是,Scala的支持从2.11版> 22场“你们班22场”的限制已取消,我想要说的是有一些限制,如案例类将不再有不应用或unapplyseq和tupled(你将不再转换情况下类数组)的功能,因为Scala仍然不支持元组多于22个值。顺便说一句,如果您不想要上述功能,您仍然可以定义大于22个字段的案例类。 –