Общие подстановочные знаки в объявлениях переменных в Scala
-
20-08-2019 - |
Вопрос
В Java я мог бы сделать это:
class MyClass {
private List<? extends MyInterface> list;
public void setList(List<MyImpl> l) { list = l; }
}
...при условии, что (MyImpl implements MyInterface
) конечно.
Какой аналог этому в Скала, при использовании Buffer
?
import java.lang.reflect._
import scala.collection.mutable._
class ScalaClass {
val list:Buffer[MyInterface] = null
def setList(l: Buffer[MyImpl]) = {
list = l
}
}
Это (конечно) не компилируется, но как мне объявить list
переменная таким образом, что она делает?
РЕДАКТИРОВАТЬ;Я добавляю еще немного.Разница, очевидно, связана с тем фактом, что в Java дженерики никогда не ковариантен в T, тогда как в Scala они могут быть как ковариантными, так и нет.Например, класс Scala List
ковариантен в T (и обязательно неизменен).Поэтому следующее скомпилирую:
class ScalaClass {
val list:List[MyInterface] = null
def setList(l: List[MyImpl]) = {
list = l
}
}
Я все еще немного борюсь с ошибкой компилятора:
Covariant type T occurs in contravariant position in ...
Например;эта ошибка компилятора возникает в объявлении класса:
class Wibble[+T] {
var some: T = _ //COMPILER ERROR HERE!
}
Я задам отдельный вопрос...
Решение
Прямой аналог
import java.util.List;
List<? extends MyInterface> list;
является
import java.util.List
var list : List[_ <: MyInterface] = _;
То же самое с Buffer
Чтобы ответить на комментарий, который вы сделали ранее, в Java параметры типа всегда инвариантны, а не ковариантны.
Другие советы
Я совсем не уверен, что понимаю ваш вопрос (вероятно, с моей стороны недостаточно кофе), но похоже, что вы спрашиваете о универсальные классы.Если это не так, оставьте комментарий или добавьте дополнительную информацию к своему вопросу, и я перезвоню позже и отредактирую свой ответ.