如果我正确理解你的问题,答案是:你可以这样做,如果Typed
是协变的T
, i.e. trait Typed[+T]
.
Example
scala> :paste
// Entering paste mode (ctrl-D to finish)
class Typed[+T: Manifest] {
override def toString = "Typed[" + implicitly[Manifest[T]].toString + "]"
}
trait Test {
def testMap: Map[Typed[_], Int]
def foo = testMap flatMap { case (t, s) => Seq.fill(s)(t) }
}
val bar = new Test {
def testMap = Map(new Typed[Double]() -> 3, new Typed[Int]() -> 5)
}
// Hit Ctrl-D
scala> bar.foo
res0: scala.collection.immutable.Iterable[Seq[Typed[Any]]] = List(Typed[Double], Typed[Double], Typed[Double], Typed[Int], Typed[Int], Typed[Int], Typed[Int], Typed[Int])
请注意,我已经做了Typed
本例中的一个类以获得更好的输出。你当然可以坚持使用trait
.
现在,为什么这里需要协方差?
协方差基本上意味着如果A <: B
then X[A] <: X[B]
。所以如果你声明testMap
as Map[Typed[Any], Int]
while Typed
were 不变的,您不被允许通过,例如ATyped[Double]
for a Typed[Any]
虽然Double <: Any
。在这里,scala编译器似乎正在取代_
with Any
在协变的情况下(请参阅即兴评论以获取对此的详细说明)。
对于有关下划线的问题的解释,我会参考 Luigi 的答案。