Scala:如何定义返回子类实例的方法
在我正在进行的项目中,有一些代码基本上如下所示:Scala:如何定义返回子类实例的方法,scala,generics,bounded-types,Scala,Generics,Bounded Types,在我正在进行的项目中,有一些代码基本上如下所示: sealed trait Character { def tags: Seq[String] def life: Int // other defs } object Character { def addTag[T <: Character](character: T, tag: String): T = { val newTags = character.tags :+ tag // character.c
sealed trait Character {
def tags: Seq[String]
def life: Int
// other defs
}
object Character {
def addTag[T <: Character](character: T, tag: String): T = {
val newTags = character.tags :+ tag
// character.copy(tags = newTags) // this doesn't compile
character match {
case c: Person => c.copy(tags = newTags).asInstanceOf[T]
case c: Beast => c.copy(tags = newTags).asInstanceOf[T]
// ten more cases to match each subclass
......
case _ => character
}
}
}
case class Person(title: String,
firstName: String,
lastName: String,
tags: Seq[String],
life: Int,
weapon: String
) extends Character
case class Beast(name: String,
tags: Seq[String],
life: Int,
weight: Int
) extends Character
// ten other case classes that extends Character
......
密封特征字符{
def标记:Seq[字符串]
def寿命:Int
//其他DEF
}
对象字符{
def addTag[T由于copy
方法特定于每个案例类(采用不同的参数),因此不能从超类使用它。您可以做的是:
sealed trait Character {
def tags: Seq[String]
def life: Int
// other defs
}
trait Taggable[T <: Character] {
def addTags(t: T, newTags: Seq[String]): T
}
object Character {
def addTag[T <: Character: Taggable](character: T, tag: String): T = {
val newTags = character.tags :+ tag
implicitly[Taggable[T]].addTags(character, newTags)
}
}
case class Person(title: String,
firstName: String,
lastName: String,
tags: Seq[String],
life: Int,
weapon: String
) extends Character
object Person {
implicit val taggable: Taggable[Person] = new Taggable[Person] {
override def addTags(t: Person, newTags: Seq[String]): Person = t.copy(tags = newTags)
}
}
case class Beast(name: String,
tags: Seq[String],
life: Int,
weight: Int
) extends Character
Character.addTag(Person("", "", "", Seq(), 1, ""), "")
// Character.addTag(Beast("", Seq(), 1, 1) // needs implicit as well
封闭性状{
def标记:Seq[字符串]
def寿命:Int
//其他DEF
}
trait Taggable[T此版本的addTag
返回Character
,而原始代码返回正确的子类型。