jam*_*rta 0 generics types scala
我有一个类型类,我想用它来存储一种对象:
trait RetainType {
type A
}
object RetainType {
def apply[A0](): RetainType = new RetainType{
type A = A0
}
}
Run Code Online (Sandbox Code Playgroud)
鉴于以下课程:
trait Annotation
class Entity extends Annotation
Run Code Online (Sandbox Code Playgroud)
我想编译器证明RetainType.A
扩展Annotation
:
def hasAnnotation[A <: Annotation] = Unit
Run Code Online (Sandbox Code Playgroud)
但是使用RetainType
编译器似乎无法解决这个问题:
val retainType = RetainType[Entity]
hasAnnotation[RetainType.A] //throws an error: type arguments [retainType.A] do not conform to method hasAnnotation's type parameter bounds [A <: Annotation]
Run Code Online (Sandbox Code Playgroud)
如果指定了类型,它可以正常工作:
hasAnnotation[Entity] //works fine
Run Code Online (Sandbox Code Playgroud)
无论如何编译器可以证明这种关系?
你弄乱了以下的签名RetainType.apply
:
def apply[A0](): RetainType
Run Code Online (Sandbox Code Playgroud)
返回类型没有提及A0
,因此它被"遗忘".也就是说,在
val x = RetainType[Int]
Run Code Online (Sandbox Code Playgroud)
x.A
是完全抽象的; 编译器无法证明x.A = Int
因为apply
签名会删除该信息.使用细化类型:
object RetainType {
def apply[A0](): RetainType { type A = A0 } = new RetainType { override type A = A0 }
}
Run Code Online (Sandbox Code Playgroud)
您可能希望使用该Aux
模式使这个更好用:
object RetainType {
type Aux[A0] = RetainType { type A = A0 }
def apply[A0](): RetainType.Aux[A0] = new RetainType { override type A = A0 }
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
64 次 |
最近记录: |