Scala在哪里寻找暗示?

时间:2011-04-08 16:29:37

标签: scala implicit-conversion implicits

对Scala新手的隐式问题似乎是:编译器在哪里查找implicits?我的意思是隐含的,因为这个问题似乎永远不会完全形成,好像没有它的话。 :-)例如,下面integral的值来自何处?

scala> import scala.math._
import scala.math._

scala> def foo[T](t: T)(implicit integral: Integral[T]) {println(integral)}
foo: [T](t: T)(implicit integral: scala.math.Integral[T])Unit

scala> foo(0)
scala.math.Numeric$IntIsIntegral$@3dbea611

scala> foo(0L)
scala.math.Numeric$LongIsIntegral$@48c610af

对于那些决定学习第一个问题答案的人来说,另一个问题是,编译器如何选择使用哪个隐式,在某些明显模糊的情况下(但无论如何编译)?

例如,scala.Predef定义了String的两次转化:一次转换为WrappedString,另一次转换为StringOps。但是,这两个类都有很多方法,所以为什么Scala不会在调用map时抱怨歧义?

注意:这个问题的灵感来自this other question,希望以更一般的方式陈述问题。该示例是从那里复制的,因为它在答案中被引用。

2 个答案:

答案 0 :(得分:539)

答案 1 :(得分:23)

我想找出隐式参数解析的优先级,而不仅仅是找到它的位置,所以我写了一篇博文revisiting implicits without import tax(和implicit parameter precedence again之后的一些反馈)。

以下是清单:

  • 1)通过本地声明,导入,外部作用域,继承,可以无前缀访问的包对象,对当前调用作用域可见。
  • 2)隐式范围,它包含所有类型的伴随对象和包对象,它们与我们搜索的隐式类型有一些关系(即类型的包对象,类型的伴随对象)本身,它的类型构造函数(如果有的话),如果有的话,还有它的超类型和超级类型。)

如果在任一阶段我们发现多个隐式静态重载规则用于解决它。