我有这样的事情:
trait ObjectId {
val value: Long
}
case class Room(id: Option[Room.Id])
case object Room {
case class Id(value: Long) extends ObjectId
}
case class Tree(id: Option[Tree.Id])
case object Tree {
case class Id(value: Long) extends ObjectId
}
我想要做的是创建具有字段ID的类FromDB
,其类型扩展了特征ObjectId
并嵌套在T
内:
case class FromDB[T](value: T, id)
例如它应该如下工作:
FromDB[Room](Room, Room.Id)
FromDB[Tree](Tree, Tree.Id)
答案 0 :(得分:1)
您可以使用依赖类型并让类型推断为您工作:
trait ObjectId {
val value: Long
}
trait Model[T] {
type Id <: ObjectId
}
case class Room(id: Option[Room.Id])
object Room extends Model[Room] {
case class Id(value: Long) extends ObjectId
}
case class Tree(id: Option[Tree.Id])
object Tree extends Model[Tree] {
case class Id(value: Long) extends ObjectId
}
case class FromDB[T, I <: Model[T]](value: T, id: I#Id)
val room = Room(Some(Room.Id(1)))
FromDB(room, room.id.get) // compiles
FromDB(room, Tree.Id(123)) // doesn't compile
此处,Model[T]
定义了Id
类型,该类型被约束为ObjectId
的子级。 Model[T]
的每个实例都有自己的Id
实现。
在FromDB[T, I <: Model[T]]
中,如果I
是正确的id
的实例,编译器将推断Model[T]
,否则不会编译。