Scala编译器发现了什么CanBuildFrom实例?

时间:2011-11-28 08:27:39

标签: scala implicit

大家好请原谅我在Scala上提出一个愚蠢的问题。 虽然我已经在Scala中编程了大约2年,但我仍然觉得很难理解implicit的用法。我们来举一个讨论的例子:

Array(1,2,3,4).map(x => x) 

如果您查找scaladoc,则无法在map课程中找到方法Arraymap可以应用于Array(1,2,3,4)的原因是implicit def intArrayOps (xs: Array[Int]): ArrayOps[Int]中定义了隐式函数scala.Predef

但是,有两个参数列表,第二个参数列表写为implicit bf: CanBuildFrom[Array[T], B, That])。现在我想知道在CanBuildFrom上应用map时,编译器在哪里找到适合Array(1,2,3,4)类型的参数。

2 个答案:

答案 0 :(得分:9)

隐式分辨率包括在伴随对象中搜索隐式参数的类型以及随播广告隐式参数的类型参数。在上面的示例中,地图的签名如下

def map[B, That](f: (Int) => B)(implicit bf: CanBuildFrom[Array[Int], B, That]): That

由于我们没有类型要求,我们现在可以忽略它。在我们查看本地和容器范围并找不到匹配的含义之后,查找隐式的下一个位置将是CanBuildFrom的伴随对象。但它没有伴侣对象。所以我们继续并在Array中查看隐式。我们找到一个

的形式
implicit def canBuildFrom[T](implicit m: ClassManifest[T]): CanBuildFrom[Array[_], T, Array[T]]

由于我们没有类型要求和匹配隐式,因此“That”必须是Array [Int]类型并完成我们的输入。

答案 1 :(得分:7)

StackOverflow上的其他问题部分回答了这个问题。让我试一试总结一下:

您需要知道的第一部分是Scala compiler looks for implicits。您可以找到有关CanBuildFrom here的更多详细信息。

如果你已经理解了关于implicits的答案中提到的内容,那么你应该看一下Scala Collections的构造。他们的继承层次结构解释为here和列表here。所有这些都是与Builders建立起来的。有关breakOut的问题详细解释了这一点。

要了解您的知识,您应该知道如何对收藏品进行拉皮条。此外,这在this question中的StackOverflow中进行了解释。

请注意,StackOverflow的最佳答案总结在Scala-Tag-Wiki