所有人。请原谅我在Scala上问了一个愚蠢的问题。虽然我已经用Scala编程大约两年了,但我仍然发现很难理解implicit
的用法。让我们举一个例子来讨论一下:
Array(1,2,3,4).map(x => x)
如果你查找scaladoc,你不能在Array
类上找到map
方法。map
可以应用于Array(1,2,3,4)
的原因是在scala.Predef
中定义了一个隐式函数implicit def intArrayOps (xs: Array[Int]): ArrayOps[Int]
。
但是,有两个参数列表,其中第二个参数列表写为implicit bf: CanBuildFrom[Array[T], B, That])
。现在,我想知道当在Array(1,2,3,4)
上应用map
时,编译器在哪里为类型CanBuildFrom
找到合适的参数。
发布于 2011-11-28 09:45:03
隐式解决包括在伴生对象中搜索隐式参数的类型,以及在伴生对象中搜索隐式参数的类型参数。在上面的示例中,map的签名如下所示
def map[B, That](f: (Int) => B)(implicit bf: CanBuildFrom[Array[Int], B, That]): That
因为我们对此没有类型要求,所以现在可以忽略它。在我们查看本地和容器作用域后,没有找到匹配的隐式,下一个要查找隐式的地方将是CanBuildFrom的伴生对象。但是,它没有伴生对象。所以我们继续在数组中寻找隐式的。我们找到了一个形式为
implicit def canBuildFrom[T](implicit m: ClassManifest[T]): CanBuildFrom[Array[_], T, Array[T]]
由于我们没有类型要求和隐式匹配,"That“被强制为ArrayInt类型,并完成了我们的类型。
发布于 2011-11-28 09:52:59
StackOverflow上的其他问题部分回答了这个问题。让我试着总结一下:
您需要知道的第一部分是Scala compiler looks for implicits在哪里。您可以找到有关CanBuildFrom here的更多详细信息。
如果您已经理解了答案中提到的关于隐式‣的内容,那么您应该看看Scala的构造。它们的继承层次结构在here和for List here中得到了解释。所有这些都是用Builders构建的。这在一个关于breakOut的问题中有详细的解释。
为了积累你的知识,你应该知道如何拉皮条。此外,在this question的StackOverflow上对此进行了解释。
请注意,Scala-Tag-Wiki中总结了有关StackOverflow的最佳答案。
https://stackoverflow.com/questions/8293173
复制相似问题