开发者

Map<String, List<? extends T>> in Scala

In my use case I have a class with covariant type Foo[+T] and classes A <: T, B <: T, C <: T, I need to store a map "A" -> a Foo[A] instance, "B" -> a Foo[B] instance and "C" -> a Foo[C] instance, is this possible in scala?

Currently I declare my map as Map[String, Foo[T]开发者_运维知识库]] but then I can't add a Foo[A] inside, i'm being told by the compiler that Foo[T] is expected, not Foo[A], which seems caused by the lack of covariance of the Map parameter, is there a solution?

My workaround for now is to de-parameterize Foo and cast in the code, which of course doesn't please me, I saw also that I could use java collections instead but I would prefer staying with scala.

Thanks in advance for your time


Works for me, even with non-covariant mutable Maps.

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)

If Foo[T] was not covariant in T, then the last command (m += (2 -> new Foo[A])) would fail.

Note that this code works because Tuples are also covariant in their types.


Strictly speaking, the Java type Map<String, List<? extends T>> is written as:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜