【问题标题】:How to define a map with a specific type key and any single type value in Scala?如何在 Scala 中定义具有特定类型键和任何单一类型值的映射?
【发布时间】:2012-03-13 15:27:15
【问题描述】:

我需要的是类似的东西

Map[DateTime, Any]

但所有值都必须是任何一种特定类型。例如,不是一个值是 Int,另一个是 Double,第三个是 String - 所有记录都必须是向下转换为 Any 的相同特定类型。

我将把地图作为一个半类型不可知函数的参数,使用匹配/大小写来确定类型并执行特定的算法。该函数实际上将支持 一些 类型,如果提供的类型不支持,则抛出异常。

【问题讨论】:

  • 我敢打赌,巧妙地使用 Manifest 会导致编译器错误,而不是运行时错误。

标签: scala map scala-collections


【解决方案1】:

我不确定你想要什么;您似乎想要的东西几乎与泛型完全一样,但显然在细节上有一些我不理解的差异。所以我猜:

如果您的抱怨是地图的添加可以扩大值的类型:

scala> val m = Map(5 -> "fish")
m: scala.collection.immutable.Map[Int,java.lang.String] = Map(5 -> fish)


scala> m + ("foo" -> "dish")  // Type mismatch on key
<console>:9: error: type mismatch;
 found   : (java.lang.String, java.lang.String)
 required: (Int, ?)
              m + ("foo" -> "dish")

scala> m + (2 -> 44)  // Type mismatch on value
m + (2 -> 44)
res2: scala.collection.immutable.Map[Int,Any] = Map(5 -> fish, 2 -> 44)

然后您可以使用泛型和多个参数来阻止更改您提供的方法中的值类型:

def add[A,B](m: Map[A,B])(a: A, b: B) = m + (a -> b)


scala> add(m)(2, 44) 
<console>:10: error: type mismatch;
 found   : Int(44)
 required: java.lang.String
              add(m)(2, 44)

这里,AB 的类型在到达第二个参数块之前绑定到映射中的任何内容。因此您不必担心映射值类型的逆变性。

【讨论】:

  • 我知道泛型,但在这种情况下我不想要def semiAgnostic[A](m: Map[DateTime,A])。我想要def semiAgnostic(m: Map[DateTime,A]):Map[DateTime,B],其中将在函数内部自动检测 A,在进一步消耗结果的任何函数内部自动检测 B。使用 match/case 来专门化 Any 使得这种方法成为可能,但在这种情况下,Map[DateTime,Any] 将允许出现意外的集合(同时尽可能强烈地限制输入)。
  • API 使用者只需将其调用为semiAgnostic(in: Map[DateTime,Int])semiAgnostic(in: Map[DateTime,Double])semiAgnostic(in: Map[DateTime,SomeCutomClass]) 即可使用该函数,而无需将值类型指定为[A]。这是一个可用性问题:DSL 需要尽可能具有可读性和无冗余,因为受众不受编程经验要求的限制。
  • 我很好奇一个类型是否可以用作参数,而不是说明符。 Something[A]Something[B] 和简单的 Something 是不同的类型,而不是具有类型说明符作为属性的一种类型,似乎显着限制了灵活性。
  • Scala 的类型推断已经推断出您的示例中的 A。
  • @Ivan - 你的 cmets 对我来说没有意义,至少如果我们谈论的是 Scala 的话。您可能误解了某些东西,但我不能确定。似乎您抱怨您不想要泛型,因为您想要像泛型一样工作的东西,并且 API 使用者必须能够以使用泛型的方式调用函数,除非您认为泛型是问题。
猜你喜欢
  • 1970-01-01
  • 2022-08-19
  • 1970-01-01
  • 2022-10-12
  • 1970-01-01
  • 2020-06-28
  • 1970-01-01
  • 1970-01-01
  • 2021-06-27
相关资源
最近更新 更多