简体   繁体   English

Scala隐式委派与继承

[英]scala implicit delegation vs inheritance

Salutations, SO! 致敬,好!

I'm obviously some species of a scala noob. 我显然是scala noob的某些种类。 I was intrigued from the beginning by the possibility to express those tedious delegations via implicits and thought it was cool to use them throughout . 从一开始,我就对通过隐式表达那些乏味的代表团的可能性深感兴趣,并且认为在整个过程中使用它们很酷。

My issue is that type tests no longer worked as they would with inheritance. 我的问题是类型测试不再像继承那样起作用。 See bellow code, 'false' is printed 4 times (unsurprinsingly) 参见下面的代码,“ 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])
}

Is thee any way to be able to test that a T is either an A or a B underneath? 您是否有任何方法可以测试T在下面是A还是B? And a way to bind it to an A or a B variable, of course. 当然,还有一种将其绑定到A或B变量的方法。 Another way, not inheritance. 另一种方式,不是继承。

And.. is there some obvious reason why false is always the result of isInstanceOf? 并且..是否存在某些明显的原因,为什么isInstanceOf的结果始终为false? The code could have very well resulted in : true false false true. 该代码很可能导致:true false false true。

Type tests like isInstanceOf will not use implicit conversions to try to convert to the type you're testing it against. isInstanceOf这样的类型测试将不会使用隐式转换来尝试转换为要对其进行测试的类型。 When you say ca.isInstanceOf[A] , ca must be an instance of A in order to be true . 当您说ca.isInstanceOf[A]ca 必须A的实例才能为true ca and cb are not instances of A or B , so all tests should return false as expected. cacb不是AB实例,因此所有测试均应按预期返回false

This is because implicits are resolved at compile time, but isInstanceOf as checked a runtime. 这是因为隐式是在编译时解析的,但是isInstanceOf在运行时进行检查。 There's no way we can mix the two like that. 我们不可能像这样将两者混在一起。

You can use a compile-time check to see that something can be implicitly viewable as something else. 您可以使用编译时检查来查看某些内容可以隐式可见。

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]
                            ^

But this is fundamentally different as it doesn't really return true/false, it just fails to compile if it's not true. 但这是根本不同的,因为它不会真正返回true / false,否则会编译失败。 And it still wouldn't work for your example. 对于您的示例,它仍然不起作用。 Since ca is a T , the compiler wouldn't even try to implicitly convert from T => A because the conversion is defined for Ca => A . 由于caT ,所以编译器甚至不会尝试从T => A隐式转换,因为转换是为Ca => A定义Ca => A It wouldn't know at compile time that Ca is a Ca , nor which companion object to find the required implicit in. 它不会在编译时知道CaCa ,也不知道在哪个伴随对象中找到所需的隐式对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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