1

我想知道是否可以使用不同构造类型的值创建地图。像这样:

class WowClass[A <: HeyClass]

val map = Map[String, WowClass[A <: HeyClass]]()

这样的值可以是不同的孩子HeyClass

4

2 回答 2

4

您绝对可以将声明值类型的子类型存储V在映射中,但是如果您从映射中读取,您所知道的就是您获得 type 的值V,即层次结构的上限类型。如果您需要了解更多信息,则可以对这些值进行模式匹配。

trait V
case class A1() extends V
case class A2() extends V

var map = Map[String, V]()

map += ("A1" -> A1())
map += ("A2" -> A2())

map.values.head match {
  case a1: A1 => println("A1")
  case a2: A2 => println("A2")
}

如果这对您来说不够精确,请查看HLists。从某种意义上说,它们是 n 元组的类型安全实现,即具有自然数键和任意类型值的固定大小的映射。

将(只读)Map[K, V]视为函数K -> V有助于理解为什么不能直接拥有一个采用不同类型值的映射,并且它也静态地知道每个键返回的值的确切类型。给定上面的函数签名,怎么可能静态地知道 key"foo"返回一个值V1 <: V,而 key"bar"返回一个类型的值V2 <: V?这个额外的信息在某种程度上需要成为函数签名的一部分,它实际上是在 HLists 的情况下。

于 2012-08-03T12:16:54.470 回答
1

如果使用 HLists 或 HMaps,Miles Sabins Shapeless将得到准确的类型。可能值得快速查看示例,看看它们是否适合您。

于 2012-08-03T18:37:42.583 回答