Общие подстановочные знаки в объявлениях переменных в Scala

StackOverflow https://stackoverflow.com/questions/663032

Вопрос

В 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 параметры типа всегда инвариантны, а не ковариантны.

Другие советы

Я совсем не уверен, что понимаю ваш вопрос (вероятно, с моей стороны недостаточно кофе), но похоже, что вы спрашиваете о универсальные классы.Если это не так, оставьте комментарий или добавьте дополнительную информацию к своему вопросу, и я перезвоню позже и отредактирую свой ответ.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top