4

有时,对映射中键和值类型之间的依赖关系进行编码可能很有用。考虑以下类型:

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 中编码这种类型吗?如果是,如何?

4

1 回答 1

3

正如其他人指出的那样,您需要使用异构地图。shapeless 项目有一个实现:

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

请注意,您可以使用隐式值(或在我们的例子中的转换)来指示允许 (key, value) 对的哪些实例。

于 2013-10-28T20:58:02.413 回答