我有两个继承人。
trait MyTrait[T <: MyTrait[T]] {
this: T =>
}
class MyTraitImpl1 extends MyTrait[MyTraitImpl1]
class MyTraitImpl2 extends MyTrait[MyTraitImpl2]
这些继承者是互斥的,可以彼此派生,因此还有另一个用MyTrait
键入的类。
class TypedClass[T <: MyTrait](value: T) {
def anotherValue[O <: MyTrait]: O
}
如果使用anotherValue
输入MyTraitImpl1
,我可以做些什么使方法TypedClass
准确返回MyTraitImpl2
吗?
答案 0 :(得分:4)
如果您可以修改MyTrait
,MyTraitImpl1
,MyTraitImpl2
,则可以添加类型成员OtherType
trait MyTrait[T <: MyTrait[T]] {
this: T =>
type OtherType <: MyTrait[_]
}
class MyTraitImpl1 extends MyTrait[MyTraitImpl1] {
override type OtherType = MyTraitImpl2
}
class MyTraitImpl2 extends MyTrait[MyTraitImpl2] {
override type OtherType = MyTraitImpl1
}
class TypedClass[T <: MyTrait[T]](value: T) {
def anotherValue: T#OtherType = ???
}
// OR
// class TypedClass[T <: MyTrait[T]](val value: T) {
//
// def anotherValue: value.OtherType = ???
// }
new TypedClass[MyTraitImpl1](new MyTraitImpl1).anotherValue : MyTraitImpl2
new TypedClass[MyTraitImpl2](new MyTraitImpl2).anotherValue : MyTraitImpl1
// new TypedClass[MyTraitImpl1](new MyTraitImpl1).anotherValue : MyTraitImpl1 // doesn't compile
// new TypedClass[MyTraitImpl2](new MyTraitImpl2).anotherValue : MyTraitImpl2 // doesn't compile
如果您无法修改MyTrait
,MyTraitImpl1
,MyTraitImpl2
,则可以创建类型类OtherType
trait MyTrait[T <: MyTrait[T]] {
this: T =>
}
class MyTraitImpl1 extends MyTrait[MyTraitImpl1]
class MyTraitImpl2 extends MyTrait[MyTraitImpl2]
trait OtherType[T <: MyTrait[T]] {
type Out <: MyTrait[_]
}
object OtherType {
type Aux[T <: MyTrait[T], Out0 <: MyTrait[_]] = OtherType[T] { type Out = Out0 }
def instance[T <: MyTrait[T], Out0 <: MyTrait[_]]: Aux[T, Out0] = new OtherType[T] { type Out = Out0 }
implicit val otherType1: Aux[MyTraitImpl1, MyTraitImpl2] = instance
implicit val otherType2: Aux[MyTraitImpl2, MyTraitImpl1] = instance
}
class TypedClass[T <: MyTrait[T]](value: T) {
def anotherValue(implicit otherType: OtherType[T]): otherType.Out = ???
}