У меня есть этот код, который работает:
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
}
Но, я хотел бы записать это как это:
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
}
Этому второму не удается скомпилировать:
никакой неявный аргумент, соответствующий типу параметра (Foo [Интервал] {...}) => Foo [Ничто] не было найдено.
В основном:
Какие-либо идеи?
Я думаю 2-е сбои, потому что Интервал типа стирается. Я могу, по-видимому, 'подсказать' компилятор как это: (это работает, но походит на взлом),
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
}
Дарио предложил сделать T ковариантным в Foo:
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
}
Но, похоже, это добавляет слишком много ограничений в Foo, например, я не могу иметь переменную-член var типа Option[T].
ковариантный тип T встречается в контравариантной позиции в типе Option[T] параметра сеттера val=