Набор Scala.contains не дает ожидаемой ошибки несоответствия типов
Я новичок в Scala, и я изо всех сил пытаюсь понять, почему я иногда не получаю ошибку типа при предоставлении неправильного аргумента Set.contains
вот краткий пример использования REPL (2.9.1.финал):
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
, Я do сделать проверку типа:
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 ответов
Итак,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
метод. Скала явно принимая contains "Hi"
С учетом и выводя lub Int
и String
(т. е. Any
)