Scala 复制具有泛型类型的案例类

2023-12-30

我有两节课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(使用前将#替换为@)

Scala 复制具有泛型类型的案例类 的相关文章

随机推荐