如何解决在scala 2.13+ / 3.x中,我们如何解决抽象类型的菱形继承问题?
这是一个简单的例子:
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)]
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。