Scala: Implicit parameter resolution precedence

非 Y 不嫁゛ 提交于 2019-11-27 04:39:14

I wrote my own answer in the form of a blog post revisiting implicits without import tax.

Update: Furthermore, the comments from Martin Odersky in the above post revealed that the Scala 2.9.1's behavior of LocalIntFoo winning over ImportedIntFoo is in fact a bug. See implicit parameter precedence again.

  • 1) implicits visible to current invocation scope via local declaration, imports, outer scope, inheritance, package object that are accessible without prefix.
  • 2) implicit scope, which contains all sort of companion objects and package object that bear some relation to the implicit's type which we search for (i.e. package object of the type, companion object of the type itself, of its type constructor if any, of its parameters if any, and also of its supertype and supertraits).

If at either stage we find more than one implicit, static overloading rule is used to resolve it.

Update 2: When I asked Josh about Implicits without Import Tax, he explained to me that he was referring to name binding rules for implicits that are named exactly the same.

From http://www.scala-lang.org/docu/files/ScalaReference.pdf, Chapter 2:

Names in Scala identify types, values, methods, and classes which are collectively called entities. Names are introduced by local definitions and declarations (§4), inheritance (§5.1.3), import clauses (§4.7), or package clauses (§9.2) which are collectively called bindings.

Bindings of different kinds have a precedence defined on them: 1. Definitions and declarations that are local, inherited, or made available by a package clause in the same compilation unit where the definition occurs have highest precedence. 2. Explicit imports have next highest precedence. 3. Wildcard imports have next highest precedence. 4. Definitions made available by a package clause not in the compilation unit where the definition occurs have lowest precedence.

I may be mistaken, but the call to foo(1) is in the same compilation unit as LocalIntFoo, resulting in that conversion taking precedence over ImportedIntFoo.

Could someone explain how it's considered more specific using "the rules of static overloading resolution (§6.26.3)"?

There's no method overload, so 6.26.3 is utterly irrelevant here.

Overload refers to multiple methods with the same name but different parameters being defined on the same class. For example, method f in the example 6.26.1 is overloaded:

class A extends B {}
def f(x: B, y: B) = . . .
def f(x: A, y: B) = . . .
val a: A
val b: B

Implicit parameter resolution precedence is a completely different rule, and one which has a question and answer already on Stack Overflow.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!