列表状态的文档:
结果集合的类型由静态类型的列表引导。这有时会导致意外结果。例如:
// lettersOf将返回可能重复字母的Seq [Char],而不是Set def lettersOf(words:Seq [String])= words flatMap(word => word.toSet)
// lettersOf将返回Set [Char],而不是Seq def lettersOf(words:Seq [String])= words.toSet flatMap(word => word.toSeq)
我很难理解这一点。 StringOps.toSet返回一组Char,所以第一个例子最终返回Char Seq - 罚款。那讲得通。我不遵循的是为什么在第二个例子中Scala构造一个Set而不是Seq。
“生成的集合是由静态类型的列表引导”究竟是什么意思?
答案 0 :(得分:1)
由于Set类中定义了canBuildFrom方法。正如您在ScalaDoc的CanBuildFrom特征中所看到的,它具有类型参数CanBuildFrom[-From, -Elem, +To]
,其中:
From - 请求创建构建器的基础集合的类型。
Elem - 要创建的集合的元素类型。
要 - 要创建的集合的类型。
基本上,当您在集合上调用flatMap函数时,它会隐式调用Set.canBuildFrom[Char]
,返回Set[Char]
至于静态类型。当Scala在集合类型之间进行转换时,它会使用此CanBuildFrom
特征,这取决于集合的静态类型。
更新了评论
如果我们将-Xprint:typer添加到scala命令,我们可以看到在typer阶段之后Scala编译器如何解析在flatMap方法中使用的隐式方法Set.canBuildFrom [Char]
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])