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

mrg*_*mrg 7 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
Run Code Online (Sandbox Code Playgroud)

为什么我没有在那里出现类型不匹配?

如果我分配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")
                             ^
Run Code Online (Sandbox Code Playgroud)

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

oxb*_*kes 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"
                                    ^
Run Code Online (Sandbox Code Playgroud)

但是,就像你说的那样:

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

我们可以合理地得出唯一的结论是,的类型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"
                                                                        ^
Run Code Online (Sandbox Code Playgroud)

问题是传递给方法的推断类型参数toSet.Scala显然正在contains "Hi"考虑并推断IntString(即Any)的润滑