Выполняя рефакторинг в приложении scala, я столкнулся с ситуацией, когда переход от List to Set вызвал вопрос, который у меня не был раньше. У меня есть некоторое представление о дисперсии, но я хотел бы понять, что это значит для компилятора.Scala Set, что происходит с инвариантными типами?
У меня было что-то похожее на это, который компилирует и работает просто отлично:
case class MyClassList(s: List[Any])
val myList = List(("this", false)) // List[(String, Boolean)]
val listWorks = MyClassList(myList)
Тогда я изменил свой список, чтобы установить:
case class MyClassSet(s: Set[Any])
val mySet = Set(("this", false)) // Set[(String, Boolean)]
val setFails = MyClassSet(mySet)
В этот момент, создавая объект типа MyClassSet уже не согласен с тем, что я передаю Set как аргумент, даже когда он принимает Набор Людей. Теперь это стало немного запутанным, когда следующие работы (обратите внимание, что множество «такой же», как и предыдущий Инд.Сброс):
val setWorks1 = MyClassSet(Set(("this", false)))
Я считаю, что простое объяснение состоит в том, что компилятор выводя Инд.Сброс Вэл как Установите [(String, Boolean)], но когда я создаю его непосредственно в списке аргументов setWorks1, потому что он принимает Set [Any], компилятор выводит его как Set [Any]. Это делает первый пример неудачным, а второй - пропуском. Эти те же работы, что указывает на предыдущий будучи правильно:
val setWorks2 = MyClassSet(mySet.toSet[Any])
val mySetOfAny: Set[Any] = Set(("this", false), ("that", true), ("other", false))
val setWorks3 = MyClassSet(mySetOfAny)
Фактическая ошибка показана компилятором:
Error:(15, 55) type mismatch;
found : Set[(String, Boolean)]
required: Set[Any]
Note: (String, Boolean) <: Any, but trait Set is invariant in type A.
You may wish to investigate a wildcard type such as `_ <: (...)
Списки и наборы определяются следующим образом:
type List[+A] = scala.collection.immutable.List[A]
type Set[A] = immutable.Set[A]
- Является ли это разницей в дисперсии типа, которая позволяет мне передавать список «более ограниченного типа, чем любой» в качестве аргумента, но не в случае от Set?
- Разве это различие предотвращает литье или преобразование между типами?
- Является ли это главным образом компилятором «ограничение» или ожидаемое свойство инвариантного типа?
- Существуют ли какие-либо другие различия между инвариантными типами «на практике» или они сводятся к кастингу, например?
Принимая ваш ответ, так как после прочтения всех других ответов в связанных ответах я получил свой мозг вокруг него.Фактическое различие в 1) хорошо объясняет, почему Set является инвариантным (также потому, что он реализован с использованием карт с инвариантным ключом. – negative