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"考虑并推断Int和String(即Any)的润滑