【问题标题】:Scala Set.contains doesn't give expected type mismatch errorScala Set.contains 没有给出预期的类型不匹配错误
【发布时间】:2012-03-03 00:49:52
【问题描述】:

我是 Scala 新手,我很难理解为什么在向 Set.contains 提供错误参数时有时不会收到类型错误

这是一个使用 REPL (2.9.1.final) 的简单示例:

scala> val baz = Map("one" -> 1, "two" -> 2)
baz: scala.collection.immutable.Map[java.lang.String,Int] = Map(one -> 1, two -> 2)

scala> baz.values.toSet.contains("asdf")
res3: Boolean = false

为什么我没有在那里得到类型不匹配?

如果我将baz.values.toSet 分配给另一个val,然后调用contains,我进行类型检查:

scala> val bling = baz.values.toSet
bling: scala.collection.immutable.Set[Int] = Set(1, 2)

scala> bling.contains("asdf")
<console>:10: error: type mismatch;
 found   : java.lang.String("asdf")
 required: Int
              bling.contains("asdf")
                             ^

愚蠢的错误、语言的微妙之处或编译器错误?

【问题讨论】:

  • 简答:语言精妙(子类型和类型推断)

标签: scala type-conversion


【解决方案1】:

好的,所以Set 在其类型参数中是不变的,并且它的工作方式与应有的完全一样

scala> Set(1, 2, 3) contains "Hi"
<console>:8: error: type mismatch;
 found   : java.lang.String("Hi")
 required: Int
              Set(1, 2, 3) contains "Hi"
                                    ^

但是,就像你说的:

scala> Map('a -> 1, 'b -> 2, 'c -> 3).values.toSet contains "Hi"
res1: Boolean = false

我们可以合理得出的唯一结论是Set 的类型是不是 Set[Int]。如果我们明确告诉 scala 我们想要一个Set[Int],会发生什么?具有显式类型参数的同一段代码可以正常工作(即它无法编译):

scala> Map('a -> 1, 'b -> 2, 'c -> 3).values.toSet[Int] contains "Hi"
<console>:8: error: type mismatch;
 found   : java.lang.String("Hi")
 required: Int
              Map('a -> 1, 'b -> 2, 'c -> 3).values.toSet[Int] contains "Hi"
                                                                        ^

问题是推断类型参数被传递给toSet 方法。 Scala 显然将contains "Hi" 考虑在内并推断出IntString 的lub(即Any

【讨论】:

  • 你是说Scala是从集合的后续用法推断出集合的类型参数应该更广泛,比如Any ?
  • 该死的,打败我。为你+1。进一步的解释是,当你调用baz.values.toSet.contains("asdf")时,它会找到满足条件[X &gt;: Int]的最接近的类型,并且它发现XAny,这意味着你的toSet的结果是Set[Any] .因此,正如 oxbow 所提到的,您应该明确说明您希望该集合是什么类型。
  • 你不应该解释一下它是在推断Set的类型为Any吗?
  • @Daniel - 这不是我刚刚做的吗?
  • 我认为问题应该是:有哪些例子表明这是一件好事?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多