【发布时间】:2018-03-29 20:53:08
【问题描述】:
在摆弄一个涉及使用任意类型值的 Map 的 sn-p 时,我遇到了一些类型推断不一致的问题:
import reflect.runtime.universe.TypeTag
case class AnyValMap[K]( m: Map[(K, TypeTag[_]), Any] ) extends AnyVal {
def add[V](k: K, v: V)(implicit tag: TypeTag[V]) = this.copy(
m = this.m + ((k, tag) -> v)
)
def grab[V](k: K)(implicit tag: TypeTag[V]): V = m((k, tag)).asInstanceOf[V]
}
val avMap = AnyValMap[String](Map.empty).
add("a", 100).
add("b", "xyz").
add("c", 5.0).
add("d", List(1, 2, 3))
// avMap: AnyValMap[String] = AnyValMap( Map(
// (a,TypeTag[Int]) -> 100, (b,TypeTag[String]) -> xyz, (c,TypeTag[Double]) -> 5.0,
// (d,TypeTag[List[Int]]) -> List(1, 2, 3)
// ) )
avMap.grab[Int]("a")
// res1: Int = 100
avMap.grab[String]("b")
// java.util.NoSuchElementException: key not found: (b,TypeTag[String]) ...
avMap.grab[Double]("c")
// res3: Double = 5.0
avMap.grab[List[Int]]("d")
// java.util.NoSuchElementException: key not found: (d,TypeTag[scala.List[Int]]) ...
现在,如果我在 add[V] 中使用显式类型信息组装 Map,一切都会正常工作:
val avMap = AnyValMap[String](Map.empty).
add[Int]("a", 100).
add[String]("b", "xyz").
add[Double]("c", 5.0).
add[List[Int]]("d", List(1, 2, 3))
avMap.grab[Int]("a")
// res5: Int = 100
avMap.grab[String]("b")
// res6: String = xyz
avMap.grab[Double]("c")
// res7: Double = 5.0
avMap.grab[List[Int]]("d")
// res8: List[Int] = List(1, 2, 3)
我的问题回复:avMap 以前一种方式组装:
-
avMap似乎已经捕获了相应类型标签中的所有推断类型。为什么有些人无法查找? - 为什么在
Int/Double和String/List[T]之间查找类型的 Map 值不一致?也许,与 TypeTag 如何处理AnyVal和AnyRef下的类型有关?
我使用的是 Scala 2.11.12(和 2.12.x 似乎显示出同样的不一致)。提前致谢。
【问题讨论】:
标签: scala type-inference type-erasure