问题描述
这是一个简单的例子:
trait Sup {
type A
def a: A
def b: A
}
trait Sub1 extends Sup {
override type A = Product
override def a = "s" -> "s"
}
trait Sub2 extends Sup {
override type A = Serializable
override def b = "s" -> "s"
}
object SS extends Sub1 with Sub2
显然,这将导致编译错误,因为两个override type A
是互斥的。这是违反直觉的,因为产品和可序列化通常一起使用。另外,我可以定义:
trait Sup {
type A
def a: A
}
trait Sub1 extends Sup {
override type A <: Product
override def a = "s" -> "s"
}
trait Sub2 extends Sup {
override type A <: Serializable
override def b = "s" -> "s"
}
object SS extends Sub1 with Sub2 {
override type A = Product with Serializable
}
这使a和b的定义无效,因为类型A尚未得到验证,此外,override type A = Product with Serializable
行显然是一个样板,可以推断出来。
定义允许菱形混合的抽象类型的正确方法是什么,同时避免在每个实现中都明确定义样板?
解决方法
我想你失去了下界。
"s" -> "s"
具有类型(String,String)
,它是Product
(和Serializable
)的子类型,但不是A <: Product
(或{{1} }。
尝试
A <: Serializable
如果您将返回类型trait Sup {
type A
def a: A
def b: A
}
trait Sub1 extends Sup {
override type A >: (String,String) <: Product
override def a = "s" -> "s"
}
trait Sub2 extends Sup {
override type A >: (String,String) <: Serializable
override def b = "s" -> "s"
}
object SS extends Sub1 with Sub2 {
override type A = Product with Serializable
}
SS.a: (String,String)
SS.b: (String,String)
implicitly[SS.A =:= (Product with Serializable)]
,Sub1#a
指定为Sub2#b
(以上推断它们为A
,即方法重写时缩小了返回类型),则
(String,String)
你甚至可以做
trait Sup {
type A
def a: A
def b: A
}
trait Sub1 extends Sup {
override type A >: (String,String) <: Product
override def a: A = "s" -> "s"
}
trait Sub2 extends Sup {
override type A >: (String,String) <: Serializable
override def b: A = "s" -> "s"
}
object SS extends Sub1 with Sub2 {
override type A = Product with Serializable
}
SS.a: Product with Serializable
SS.b: Product with Serializable
implicitly[SS.A =:= (Product with Serializable)]