Scala:如何找出StringOps.map使用哪个CanBuildFrom实现

Abh*_*kar 3 string scala mapreduce builder implicit-conversion

我正在通过"Scala for the Impatient"一书中的练习来学习Scala.一个问题是:

结果"abc".map(_.toUpper)是a String,但结果 "abc".map(_.toInt)是a Vector.找出为什么.

在阅读" Scala集合的架构 "之后,我认为这是因为CanBuildFrom选择了不同的隐式实现.如何找出为上述表达式选择的?

sen*_*nia 8

你可以使用show{reify{...}}这样的所有暗示:

scala> import scala.reflect.runtime.{universe => ru}
import scala.reflect.runtime.{universe=>ru}

scala> ru.show{ ru.reify{ "abc".map(_.toUpper) }.tree }
res0: String = Predef.augmentString("abc").map(((x$1) => Predef.charWrapper(x$1).toUpper))(Predef.StringCanBuildFrom)

scala> ru.show{ ru.reify{ "123".map(_.toInt) }.tree }
res1: String = Predef.augmentString("123").map(((x$1) => x$1.toInt))(Predef.fallbackStringCanBuildFrom)
Run Code Online (Sandbox Code Playgroud)

所以Predef.StringCanBuildFrom用型CanBuildFrom[String,Char,String]用于_.toUpperPredef.fallbackStringCanBuildFrom同类型CanBuildFrom[String,Int,IndexedSeq[Int]]用于_.toInt.

scala> Predef.StringCanBuildFrom
res2: scala.collection.generic.CanBuildFrom[String,Char,String] = scala.Predef$$anon$3@43b7a6fa

scala> Predef.fallbackStringCanBuildFrom[Int]
res3: scala.collection.generic.CanBuildFrom[String,Int,scala.collection.immutable.IndexedSeq[Int]] = scala.LowPriorityImplicits$$anon$4@61af1aa0
Run Code Online (Sandbox Code Playgroud)

请注意,类型不是Vector而是IndexedSeq.Vector具体实施.