Scala 是否可以更新实现公共特征的任何案例类的字段
让我们假设我们有一个共同特征模型Scala 是否可以更新实现公共特征的任何案例类的字段,scala,case-class,shapeless,Scala,Case Class,Shapeless,让我们假设我们有一个共同特征模型 trait Model { def id: String def updated: Date } 我们有两个案例类扩展了这个特性 case class C1(id: String, updated: Date, foo: String) extends Model case class C2(id: String, updated: Date, bar: Int) extends Model 是否可以编写下面这样的实用程序函数,将模型作为参数并返回一
trait Model {
def id: String
def updated: Date
}
我们有两个案例类扩展了这个特性
case class C1(id: String, updated: Date, foo: String) extends Model
case class C2(id: String, updated: Date, bar: Int) extends Model
是否可以编写下面这样的实用程序函数,将模型作为参数并返回一个副本,其中包含更新字段的更新值
object Model {
def update[T <: Model](model: T): T = {
model.copy(updated = new Date) // This code does not compile.
}
}
对象模型{
def update[Tcopy
是在您的案例类上定义的方法。而不是在您的基本trait模型上定义的方法。如果您有:
trait Model {
def id: String
def updated: Date
}
case class C1(id: String, updated: Date, foo: String) extends Model
case class C2(id: String, updated: Date, bar: Int) extends Model
class NotACaseClass(val id: String, val updated: Date) extends Model
notacesclass
是Model
的一个非常有效的子类,您可以将它的一个实例传递给您的update
函数,但是祝您好运找到一个copy
方法:)您的代码有两个问题:
copy
没有在trait上定义,因此您需要在trait上定义一些可以使用的内容
为了使update
返回T
而不是Model
,每个Model
必须知道其实际的子类型
您可以这样修复它:
trait Model[T <: Model[T]] {
def id: String
def updated: Date
def withDate(d: Date): T
}
case class C1(id: String, updated: Date, foo: String) extends Model[C1] { def withDate(d: Date) = copy(updated = d) }
case class C2(id: String, updated: Date, bar: Int) extends Model[C2] { def withDate(d: Date) = copy(updated = d) }
object Model {
def update[T <: Model[T]](model: T): T = {
model.withDate(new Date) // This code does not compile.
}
}
您可以在这里编写的“最佳”抽象是镜头
,它看起来像:
trait Lens[A, B]{
def get: A => B
def set: (A, B) => A
}
def update[A](that: A, value: Date)(implicit tLens: Lens[A, Date]): A =
tLens set (that, value)
因此,您的代码如下所示:
trait Lens[A, B]{
def get: A => B
def set: (A, B) => A
}
def update[A](that: A, value: Date)(implicit tLens: Lens[A, Date]): A =
tLens set (that, value)
@米利萨宾,但这种过度工程几乎不是一个可行的选择(现在,你可以随意称我为“有偏见的”甚至是白痴:-))。或者除此之外还有其他方法吗?它回答了为什么它不起作用,但对给定的问题没有提供解决方案。镜头是好的……但我想我们可能可以推断出给定一个不成形的LabelledGeneric
的镜头用于所讨论的案例类。@MilesSabin是的,我打赌你是对的。如果你写它,我会把这个答案给你。这是这是我计划采用的方法。但我仍然想知道是否有一种方法可以自动完成这项工作并确保键入安全。因此,即使withDate
的每个子类型的Model
都有相同的代码行,但每个类都需要重写,对吗?