泛型 – 带有通配符类型参数的map上的flatMap
发布时间:2020-12-16 09:52:41 所属栏目:安全 来源:网络整理
导读:我想写这样的东西: trait Typed[T]trait Test { def testMap: Map[Typed[_],Int] def test = testMap.flatMap {case (typed,size) = Seq.fill(size)(typed)}} 但是我收到以下错误: error: no type parameters for method flatMap: (f: ((Typed[_],Int)) =
我想写这样的东西:
trait Typed[T] trait Test { def testMap: Map[Typed[_],Int] def test = testMap.flatMap {case (typed,size) => Seq.fill(size)(typed)} } 但是我收到以下错误: error: no type parameters for method flatMap: (f: ((Typed[_],Int)) => Traversable[B])(implicit bf: scala.collection.generic.CanBuildFrom[scala.collection.immutable.Map[com.quarta.service.querybuilder.Typed[_],Int],B,That])That exist so that it can be applied to arguments (((Typed[_],Int)) => Seq[Typed[_0]] forSome { type _0 }) --- because --- argument expression's type is not compatible with formal parameter type; found : ((Typed[_],Int)) => Seq[Typed[_0]] forSome { type _0 } required: ((Typed[_],Int)) => Traversable[?B] def test = testMap.flatMap {case (typed,size) => Seq.fill(size)(typed)} 如果将testMap类型更改为:此代码有效: def testMap: Map[Typed[Any],Int] 有什么区别以及如何解决我的问题? 解决方法
如果我正确地理解了你的问题,答案是:如果Typed在T中是协变的,你可以这样做,即trait Typed [T].
例 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[Int],Typed[Int]) 请注意,我已在此示例中键入了一个类以获得更好的输出.你当然可以坚持一个特质. 现在,为什么需要协方差? 协方差基本上意味着如果A <:B则X [A] <:X [B].因此,如果您将testMap声明为Map [Typed [Any],而Typed是不变的,则不允许您传入,例如对于类型为[Any]的类型为[Double],即使Double< ;: Any.在这里,scala编译器似乎在协变情况下用Any替换_(请参阅extempore的注释以详细阐述). 有关下划线问题的解释,我会参考Luigi的答案. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |