Подтвердить что ты не робот

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

В Java я могу сделать это:

class MyClass {
    private List<? extends MyInterface> list;

    public void setList(List<MyImpl> l) { list = l; }
}

... предполагая, что (MyImpl implements MyInterface), конечно.

Что такое аналог для этого в Scala при использовании 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!
 }

Я собираюсь задать отдельный вопрос...

4b9b3361

Ответ 1

Прямой аналог

import java.util.List;
List<? extends MyInterface> list;

есть

import java.util.List
var list : List[_ <: MyInterface]  = _;

То же самое касается буфера

Чтобы ответить на комментарий, который вы сделали ухер, параметры типа Java всегда являются инвариантными, а не ковариантными.

Ответ 2

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