Scala Set.contains不会给出预期的类型不匹配错误

时间:2012-03-02 16:23:43

标签: scala type-conversion

我是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")
                             ^

愚蠢的错误,语言微妙或编译错误?

1 个答案:

答案 0 :(得分:12)

好的,所以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的润滑(即Any