Scala 2.11.7
Example code
class A {
def meth() = println("A.meth()")
}
object A {
implicit def bool2A(b: Boolean): A = new A()
}
コンパニオンオブジェクト
レシーバの場合、変換先のコンパニオンオブジェクトで定義したimplicit
はタダでは使えないので、import
か型注釈を追加する必要がある。(変換元なら問題なし)
object Main extends {
import A._
def main(args: Array[String]) = {
true meth // import無しではエラー
(true: A) meth
}
}
おそらくメソッドから変換先の型を推論するので、import
したコンパニオンオブジェクトだけを対象とすることで探索が複雑にならないようにしているのだと思う。
implicitの候補が複数ある場合
親子
object Main extends {
import A._
import B._
def main(args: Array[String]) = {
true meth
}
}
class B extends A {
override def meth() = println("B.meth()")
}
object B {
implicit def bool2B(b: Boolean): B = new B()
}
import
の順序を変えてもB.meth()
が呼ばれるので、サブクラスを優先するものと思われる。(ちなみに引数の変換の場合は、引数の型に依存)
兄弟
object Main extends {
import B._
import C._
def main(args: Array[String]) = {
true meth
}
}
class B extends A {
override def meth() = println("B.meth()")
}
object B {
implicit def bool2B(b: Boolean): B = new B()
}
class C extends A {
override def meth() = println("C.meth()")
}
object C {
implicit def bool2C(b: Boolean): C = new C()
}
曖昧なのでコンパイルエラー。
ImplicitConversion.scala:5: error: type mismatch;
found : Boolean(true)
required: ?{def meth: ?}
Note that implicit conversions are not applicable because they are ambiguous:
both method bool2B in object B of type (b: Boolean)B
and method bool2C in object C of type (b: Boolean)C
are possible conversion functions from Boolean(true) to ?{def meth: ?}
true meth
^