了解List中的flatMap声明

use*_*882 5 collections scala implicit

我只是看了一下List.flatMap宣言,对此感到有些惊讶.

final override def flatMap[B, That](f: A => GenTraversableOnce[B])
                 (implicit bf: CanBuildFrom[List[A], B, That]): That
Run Code Online (Sandbox Code Playgroud)

在哪里object List定义:

implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, List[A]] =
    ReusableCBF.asInstanceOf[GenericCanBuildFrom[A]]
Run Code Online (Sandbox Code Playgroud)

因此,如果我们调用flatMapa,List我们将获得List并且我没有看到That类型中的任何点,如果它总是被推断为List[B](因为implicit).

Yuv*_*kov 5

所以,如果我们调用flatMapa,List[A]我们就会得到它List[A],That如果它总是被推断出来,我看不到类型中的任何一点List[B]

你遗漏的一件事flatMap是实际上没有定义List[+A].它是继承自的TraversableLike,这是大多数Scalas集合使用的特征.它们中的每一个都可以提供隐式CanBuildFrom,可以覆盖它以提供不同的结果集合.

如果您想要了解自己可以使用的自定义内容CanBuildFrom:

scala> :pa
// Entering paste mode (ctrl-D to finish)

import scala.collection.generic.CanBuildFrom
import scala.collection.immutable._
import scala.collection.mutable
import scala.{List, Vector}

implicit val listToVectorCBF = new CanBuildFrom[List[Int], Int, Vector[Int]] {
  override def apply(from: List[Int]): mutable.Builder[Int, Vector[Int]] = this.apply()
  override def apply(): mutable.Builder[Int, Vector[Int]] = Vector.newBuilder
}

// Exiting paste mode, now interpreting.

scala> List(1,2,3).flatMap(List(_))
res6: Vector[Int] = Vector(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)