Scala Set.contains не дает ожидаемой ошибки несоответствия типов - PullRequest
7 голосов
/ 02 марта 2012

Я новичок в 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 Ответ

12 голосов
/ 02 марта 2012

ОК, поэтому 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" и делает вывод, что Int и String (то есть Any)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...