Scala嵌套具有特征的类型

时间:2016-08-23 11:19:47

标签: scala

我有这样的事情:

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)

1 个答案:

答案 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],否则不会编译。