简体   繁体   中英

Why Scala's compiler is not able to use an implicit conversion of an inherited type?

I am currently digging in the implicit topic, and got myself stuck with this case :

class A
class B extends A

object A { implicit def b2String(b: B): String = "B" }
object B { implicit def a2String(a: A): String = "A" }

val s: String = new B // This does not compile

I know this is a bit of an edge case, but I wanted to understand it. Shouldn't the compiler pick A's implicit (b2String) ? Or does (as it seems) it stuck to the most specific type's companion object (B) ? Does that mean inherited type's companion object implicits are not inherited ?

Thank you in advance.

EDIT : If A's companion object is deleted, then it compiles and the value of s is "A". So the compiler is able to figure out than an implicit valid for A is also valid for B.

EDIT : If I do the following changes, this also compiles :

  class A
  class B extends A

  object A { implicit def b2String(b: B): Int = 1 }
  object B { implicit def a2String(a: A): String = "A" }

  val s: String = new B
  val i: Int = new B

So companion objects implicits are inherited.

它无法编译,因为有两个可用的隐式变量,根据http://scala-lang.org/files/archive/spec/2.11/06-expressions.html#overloading-resolution中的规则,它们具有相同的相对权重: b2String在得到1 a2String ,因为它是在派生类中的同伴对象, a2String得到1比b2String ,因为它更具体。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM