Карта <Строка, Список <? расширяет T >> в Scala - PullRequest
2 голосов
/ 05 августа 2011

В моем случае использования у меня есть класс с ковариантным типом Foo [+ T] и классами A <: T, B <: T, C <: T, Мне нужно хранить карту «A» -> экземпляр Foo [A], «B» -> экземпляр Foo [B] и «C» -> экземпляр Foo [C], возможно ли это в scala?

В настоящее время я объявляю свою карту как Map [String, Foo [T]]], но тогда я не могу добавить Foo [A] внутрь, мне сообщают компилятор, что Foo [T] ожидается, а не Foo [A], который, по-видимому, вызван отсутствием ковариации параметра Map, есть ли решение?

Мой обходной путь на данный момент - это де-параметризация Foo и приведение кода, что, конечно, меня не радует, я также увидел, что вместо этого я могу использовать java-коллекции, но я бы предпочел остаться с scala.

Заранее спасибо за ваше время

Ответы [ 2 ]

6 голосов
/ 05 августа 2011

Работает для меня, даже с нековариантными изменяемыми картами.

Welcome to Scala version 2.9.1.RC1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_24).

scala> class T
defined class T

scala> class A extends T
defined class A

scala> class Foo[+T]
defined class Foo

scala>   val m = collection.mutable.Map[Int, Foo[T]]()
m: scala.collection.mutable.Map[Int,Foo[T]] = Map()

scala>   val m2 = m + (1 -> new Foo[A])
m2: scala.collection.mutable.Map[Int,Foo[T]] = Map(1 -> Foo@48f2818d)

scala>   m += (2 -> new Foo[A])
res0: m.type = Map(2 -> Foo@12caa79c)

Если Foo[T] не является ковариантным в T, то последняя команда (m += (2 -> new Foo[A])) не будет выполнена.

Обратите внимание, что этот код работает, потому что кортежи также ковариантны по своим типам.

2 голосов
/ 06 августа 2011

Строго говоря, тип Java Map<String, List<? extends T>> записывается как:

Map[String, List[_ <: T]]
...