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]]
精彩评论