我有一个代表我的域名的案例类:
case class MyModel(rawValue: String, transformedValue: String)
rawValue映射到数据库中的值,并且已正确解析和绑定。我要做的是将transformedValue
添加到我的模型中:这个值只是我在rawValue上执行的一些任意转换。它不映射到数据库/查询中的任何数据。
我有一个解析器(在添加transformedValue
之前),如下所示:
val parser = {
get[String]("rawValue") map {
case rawValue => MyModel(rawValue)
}
}
由于MyModel
是不可移植的,我无法在创建后插入transformedValue
,所以最好的方法是什么,在哪里添加并添加此转换(例如添加ad-hoc值到模型)最好不使用变量?
来自Java,我可能只是在域类中添加了一个getTransformedValue
getter,它在rawValue属性上执行此转换。
答案 0 :(得分:2)
由于transformedValue
似乎是派生属性,而不是构造函数中提供的属性,因此您可以将其定义为函数体中的属性,可能使用lazy
限定符这样它只能按需计算(例如只计算一次):
case class MyModel(rawValue: String) {
lazy val transformedValue: String = {
// Transformation logic, e.g.
rawValue.toLowerCase()
}
}
val
在定义时进行评估;调用def
时会对其进行评估。第一次访问时会评估lazy val
。
在很少需要昂贵的计算或逻辑需要的情况下使用lazy
可能是合适的。但对于大多数情况,应使用常规val
。 Quoting:
lazy val 不免费(甚至便宜)。只有在绝对需要懒惰才能正确使用时才使用它,而不是用于优化。
答案 1 :(得分:1)
我不明白你为什么不在解析器本身进行转换:
def transformation(rawValue: String): String = ...
val parser = {
get[String]("rawValue") map {
case rawValue => MyModel(rawValue, transformation(rawValue))
}
}
或者如果您因某些原因不想在那里进行,可以使用copy
创建一个新值MyModel
的副本:
val model = MyModel("value", ..)
val modelWithTransform = model.copy(transformedValue = transformation(model.rawValue))
您还可以重载apply
以在配对对象中自动应用转换:
case class MyModel(rawValue: String, transformedValue: String)
object MyModel {
def apply(value: String): MyModel = MyModel(rawValue, transformation(rawValue))
val parser = {
get[String]("rawValue") map {
case rawValue => MyModel(rawValue)
}
}
}
MyModel
可能是不可变的,但您可以随时创建另一个副本,并更改一些值。
答案 2 :(得分:0)
事实证明它比我想象的要容易,解决方案确实看起来像我在Java中所说的那样:
我只是向MyModel添加一个执行此转换的函数:
case class MyModel(rawValue: String) {
def transformedValue = {
// do the transformation here and return it
}
}