了解Scala的flatmap类型转换

时间:2013-05-22 19:48:24

标签: scala scala-collections

列表状态的文档:

  

结果集合的类型由静态类型的列表引导。这有时会导致意外结果。例如:

     

// 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。

“生成的集合是由静态类型的列表引导”究竟是什么意思?

1 个答案:

答案 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])
相关问题