我有两节课PixelObject
, ImageRefObject
还有更多,但这里只是这两个类来简化事情。它们都是a的子类trait Object
包含一个 uid。
我需要通用方法,它将使用给定的新实例复制案例类实例uid
。我需要它的原因是因为我的任务是创建一个 ObjectRepository 类,它将保存任何子类的实例Object
并用新的返回它uid
。
我的尝试:
trait Object {
val uid: Option[String]
}
trait UidBuilder[A <: Object] {
def withUid(uid: String): A = {
this match {
case x: PixelObject => x.copy(uid = Some(uid))
case x: ImageRefObject => x.copy(uid = Some(uid))
}
}
}
case class PixelObject(uid: Option[String], targetUrl: String) extends Object with UidBuilder[PixelObject]
case class ImageRefObject(uid: Option[String], targetUrl: String, imageUrl: String) extends Object with UidBuilder[ImageRefObject]
val pix = PixelObject(Some("oldUid"), "http://example.com")
val newPix = pix.withUid("newUid")
println(newPix.toString)
但我收到以下错误:
➜ ~ scala /tmp/1.scala
/tmp/1.scala:9: error: type mismatch;
found : this.PixelObject
required: A
case x: PixelObject => x.copy(uid = Some(uid))
^
/tmp/1.scala:10: error: type mismatch;
found : this.ImageRefObject
required: A
case x: ImageRefObject => x.copy(uid = Some(uid))
^
two errors found
我会坚持肖恩提出的解决方案。几个月前我也做了同样的事情。例如:
trait Entity[E <: Entity[E]] {
// self-typing to E to force withId to return this type
self: E => def id: Option[Long]
def withId(id: Long): E
}
case class Foo extends Entity[Foo] {
def withId(id:Long) = this.copy(id = Some(id))
}
因此,您不必定义一个与您的特征的所有实现相匹配的 UuiBuilder,而是在您的实现本身中定义该方法。您可能不想每次添加新实现时都修改 UuiBuilder。
此外,我还建议您使用自输入来强制 withId() 方法的返回类型。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)