Карта‹Строка, Список‹? расширяет T›› в Scala

В моем случае использования у меня есть класс с ковариантным типом 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.

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


person jolivier    schedule 04.08.2011    source источник
comment
вы говорите об изменяемых или неизменяемых картах? с неизменяемыми картами тип значения является ковариантным...   -  person Kim Stebel    schedule 05.08.2011
comment
да, на самом деле я использовал реализацию HashMap как глупый рефлекс из Java, который неверен в scala, а HashMap не является ковариантным ›‹   -  person jolivier    schedule 06.08.2011


Ответы (2)


У меня работает даже с нековариантными изменчивыми картами.

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])) завершилась бы неудачно.

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

person Kipton Barros    schedule 04.08.2011
comment
да, извините, проблема, которую я опубликовал, отличалась от проблемы, которая была у меня в моем коде, потому что у меня все еще есть интерфейс Java Reflex Map -> реализация HashMap, которая неверна в scala, поскольку Map является ковариантным, но не HashMap, спасибо - person jolivier; 06.08.2011

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

Map[String, List[_ <: T]]
person Daniel C. Sobral    schedule 05.08.2011