Ale*_*ack 9 generics scala type-inference
我有这个代码有效:
def testTypeSpecialization: String = {
class Foo[T]
def add[T](obj: Foo[T]): Foo[T] = obj
def addInt[X <% Foo[Int]](obj: X): X = {
add(obj)
obj
}
val foo = addInt(new Foo[Int] {
def someMethod: String = "Hello world"
})
foo.someMethod
}
Run Code Online (Sandbox Code Playgroud)
但是,我想这样写:
def testTypeSpecialization: String = {
class Foo[T]
def add[X, T <% Foo[X](obj: T): T = obj
val foo = add(new Foo[Int] {
def someMethod: String = "Hello world"
})
foo.someMethod
}
Run Code Online (Sandbox Code Playgroud)
第二个无法编译:
没有隐式参数匹配参数类型(Foo [Int] {...})=> Foo [Nothing]被找到.
基本上:
有任何想法吗?
我认为第二个失败是因为Int类型正在被删除.我显然可以像这样'暗示'编译器:(这有效,但看起来像是黑客)
def testTypeSpecialization = {
class Foo[T]
def add[X, T <% Foo[X]](dummy: X, obj: T): T = obj
val foo = add(2, new Foo[Int] {
def someMethod: String = "Hello world"
})
foo.someMethod
}
Run Code Online (Sandbox Code Playgroud)
Dario 建议在 Foo 中使 T 协变:
def testTypeSpecialization: String = {
class Foo[+T] {
var _val: Option[T]
}
def add[X, T <% Foo[X](obj: T): T = obj
val foo = add(new Foo[Int] {
def someMethod: String = "Hello world"
})
foo.someMethod
}
Run Code Online (Sandbox Code Playgroud)
但是,这似乎给 Foo 添加了太多限制,例如我不能拥有 Option[T] 类型的 var 成员变量。
协变类型 T 出现在 setter val =参数的类型 Option[T] 中的逆变位置