В документах для списка указано:
Тип результирующей коллекции определяется статическим типом списка. Иногда это может приводить к неожиданным результатам. Например:
// letterOf вернет Seq [Char] вероятных повторяющихся букв вместо Set def letterOf (words: Seq [String]) = words flatMap (word => word.toSet)
// letterOf вернет Set [Char], а не Seq def letterOf (words: Seq [String]) = words.toSet flatMap (word => word.toSeq)
Мне сложно это понять. StringOps.toSet возвращает Set of Char, поэтому в первом примере возвращается Char Seq - нормально. В этом есть смысл. Я не понимаю, почему во втором примере Scala создает Set вместо Seq.
Что именно здесь означает «результирующая коллекция руководствуется статическим типом списка»?
1 ответ
Из-за определения метода canBuildFrom в классе Set. Как вы можете видеть в ScalaDoc's CanBuildFrom, у него есть три параметра типа CanBuildFrom[-From, -Elem, +To]
, где:
От - тип базовой коллекции, которая запрашивает создание построителя.
Elem - тип элемента создаваемой коллекции.
Кому - тип создаваемой коллекции.
Обычно, когда вы вызываете свою функцию flatMap для набора, она неявно вызывает Set.canBuildFrom[Char]
, которые возвращают Set[Char]
Что касается статического типа. Когда Scala пытается выполнить преобразование между типами коллекций, он использует эту черту CanBuildFrom
, которая зависит от статического типа вашей коллекции.
Обновлено для комментария
Если мы добавим -Xprint: typer к команде scala, мы увидим, как компилятор Scala после фазы typer разрешает неявный метод Set.canBuildFrom [Char], который используется в методе flatMap
def lettersOf(words: Seq[String]): scala.collection.immutable.Set[Char] = words.toSet[String].flatMap[Char, scala.collection.immutable.Set[Char]](((word: String) => scala.this.Predef.augmentString(word).toSeq))(immutable.this.Set.canBuildFrom[Char])
Похожие вопросы
Новые вопросы
scala
Scala - это язык программирования общего назначения, в основном предназначенный для виртуальной машины Java. Разработанный для краткого, элегантного и безопасного для типов представления общих шаблонов программирования, он сочетает в себе как императивный, так и функциональный стили программирования. Его ключевые особенности: продвинутая система статического типа с выводом типа; типы функций; сопоставления с образцом ; неявные параметры и преобразования; перегрузка оператора; полная совместимость с Java; совпадение