有时,在地图中的键类型和值之间编码依赖关系可能很有用。请考虑以下类型:
type MyPairs = Seq[(TypeTag[T], T) forSome {type T}]
此处序列中的每对应具有相同的类型T
。但就类似地图的使用而言,这种类型并不是很方便。但是我无法对Map[K, V]
表达这种依赖,因为Map
有两个独立的类型参数,似乎我不能以任何方式将它们“分组”以使用单个存在类型。天真的变种
type MyMap = Map[TypeTag[T], T] forSome {type T}
只强制单一类型T
。适用于所有MyMap
个条目,但不适用于每个条目。
我认为另一个极端是
type MyMap = Map[TypeTag[_], _]
但是,这当然是一个过于宽泛的定义,它允许键值类型的任何组合。
所以我的问题是,可以在Scala中编码这样的类型吗?如果是,怎么样?
答案 0 :(得分:1)
正如其他人所指出的,你需要使用异质地图。无形的项目实现了这个:
https://github.com/milessabin/shapeless/wiki/Feature-overview:-shapeless-1.2.4#heterogenous-maps
这允许你这样做:
import shapeless._
class Constrainer[K, V]
implicit def allowed[T] = new Constrainer[Class[T], T]
val hmap = HMap[Constrainer](classOf[String] -> "Hi there", classOf[Int] -> 3) // this compiles
val hmapFail = HMap[Constrainer](classOf[String] -> 3) // this won't compile
对于使用TypeTag的具体示例:
import shapeless._
import scala.reflect.runtime.universe._
class Constrainer[K, V]
implicit def allowed[T] = new Constrainer[TypeTag[T], T]
val hmap = HMap[Constrainer](typeTag[String] -> "hello", typeTag[Int] -> 2) // this compiles
val hmapFail = HMap[Constrainer](typeTag[String] -> 3) // this won't compile
请注意,您可以使用隐式值(或我们的情况下的转换)来指示允许(键,值)对的实例。