scala隐式委派vs继承

时间:2015-05-07 19:36:39

标签: scala

致敬,SO!

我显然是scala noob的一些种类。我从一开始就很有兴趣通过暗示来表达那些乏味的代表团,并认为在整个过程中使用它们很酷。

我的问题是类型测试不再像继承那样工作。请参阅下面的代码,'false'打印4次(无意义)

trait T { def bar = Unit }
class A { def aFoo() = print("AFooooo") }
class B { def bFoo() = print("BFooooo") }

object Ca { implicit def delToA(me : Ca) : A = me.a}
class Ca(val a : A) extends T { }

object Cb { implicit def delToB(me : Cb) : B = me.b}
class Cb(val b : B) extends T { }

object MyName extends App {
  val ca : T = new Ca(new A)
  val cb : T = new Cb(new B)

  println(ca.isInstanceOf[A])
  println(ca.isInstanceOf[B])

  println( cb.isInstanceOf[A])
  println(cb.isInstanceOf[B])
}

你是否有能力测试T是下面的A还是B?当然,还有一种将它绑定到A或B变量的方法。 另一种方式,而不是继承。

并且..有一些明显的原因,为什么false总是isInstanceOf的结果?代码可能很好地导致:true false false true。

1 个答案:

答案 0 :(得分:0)

isInstanceOf之类的类型测试不会使用隐式转换来尝试转换为您正在测试它的类型。当您说ca.isInstanceOf[A]时,ca 必须成为A的实例才能成为truecacb不是AB的实例,因此所有测试都应按预期返回false

这是因为implicits在编译时被解析,但isInstanceOf在运行时被检查。我们无法将这两者混合在一起。

您可以使用编译时检查来查看某些内容可以隐式查看为其他内容。

implicit class Wrapper[A](a: A) {
    def isImplicitly[B](implicit ev: A => B): Boolean = true
}

class Y
class Z

implicit def z2y(z: Z): Y = new Y

val y = new Y
val z = new Z

scala> z.isImplicitly[Y]
res66: Boolean = true

scala> y.isImplicitly[Z]
<console>:39: error: No implicit view available from Y => Z.
              y.isImplicitly[Z]
                            ^

但是这根本不同,因为它并没有真正返回true / false,如果它不是真的就无法编译。它仍然不适用于你的例子。由于caT,编译器甚至不会尝试隐式转换T => A,因为转换是为Ca => A定义的。它不会在编译时知道CaCa,也不知道找到所需隐含的伴随对象。