假设我有值类的以下代码:
class Meters(val x: Int) extends AnyVal {
def +(m: Meters): Meters = new Meters(x + m.x)
}
class Seconds(val x: Int) extends AnyVal {
def +(s: Seconds): Seconds = new Seconds(x + s.x)
}
有什么方法可以删除“+”方法的重复吗? 有点像:
abstract class Units[T <: Units[T]](val x: Int) extends AnyVal {
def +(other: T): T = T(x + other.x)
}
除非我不能从值类继承,否则我绝对不能像构造函数一样使用T
。
答案 0 :(得分:2)
您可以将universal trait与类型类一起使用,让我们开始定义特征。
trait Sum[T <: Sum[T]] extends Any {
val x: Int
def +(other: T)(implicit evidence : FromInt[T]): T = evidence.fromInt(x + other.x)
}
现在我们需要一个类型类来告诉我们如何从一个整数变为某种类型,让我们定义它并调用它FromInt
trait FromInt[T] {
def fromInt(x: Int) : T
}
现在让我们定义一个简单的Meters
值类
class Meters(val x :Int) extends AnyVal with Sum[Meters]
在伴随对象中,我们可以提供我们定义的类型类的隐式值。
object Meters{
implicit val intConstructable : FromInt[Meters] = new FromInt[Meters] {
override def fromInt(x: Int) = new Meters(x)
}
}
现在我们可以做到
val added = new Meters(2) + new Meters(3)
println(added.x)