【发布时间】:2021-03-03 18:42:10
【问题描述】:
我正在做一个附带项目,试图在 Scala 中实现不可变聚合。我的想法是让基本特征AggregateRoot 具有一些常见的行为。子类将是建模为案例类的实际聚合。目前,我不喜欢一件事,那就是我不能从基本 trait 调用 copy 方法,原因有两个:
- 我无法访问基本特征内的
copy方法 - 我不知道
copy方法会有多少参数
我对无形库有一些基本知识,我认为它可能对这种情况有所帮助。我的想法是将标记字段列表传递给特征中的基方法,该方法将替换它们并返回案例类的新实例。 作为朝着这个方向迈出的一步,我正在尝试创建一个方法,该方法将使用 shapeless 在开始时复制一个字段,但我一直遇到相同的错误,编译器找不到更新程序的隐式。
这是我尝试使用的简化代码片段:
import shapeless._
import shapeless.labelled.FieldType
import shapeless.ops.record.Updater
import shapeless.record._
import shapeless.syntax.singleton._
trait AggregateRoot[T <: AggregateRoot[T]] {
self: T =>
def makeCopy[L <: HList, K, V](ft: FieldType[K, V])(
implicit
labeledGen: LabelledGeneric.Aux[T, L],
updater: Updater.Aux[L, FieldType[K, V], L],
witness: Witness.Aux[K]): T = {
val labeledHList = labeledGen.to(this)
val result = labeledHList.updated(witness, ft)
labeledGen.from(result)
}
}
case class User(id: String, age: Int) extends AggregateRoot[User]()
val user1 = User("123", 10)
val ageChange = "age" ->> 22
val user2 = user1.makeCopy(ageChange)
由于我不是经验丰富的无形用户,我不确定为什么它找不到请求的隐式。 shapeless 的版本是 2.3.3。
【问题讨论】:
-
我想说的是,添加自己的
withX方法集而不是copy会更容易、更简单和更好
标签: scala generics shapeless case-class