简体   繁体   English

Scala 中的逆变用法

[英]Contravariance usage in Scala

As per the definition of contravariance (super class instances will be accepted), my last statement in the below code snippet, should be accepted;根据逆变的定义(超级 class 个实例将被接受),我在下面代码片段中的最后一个陈述应该被接受; but it is thrown with type error.但它被抛出类型错误。 Can you please correct my understanding.你能纠正我的理解吗?

  class A
  class B extends A
  class C extends B
  
  abstract class Box[-T] {
     def set(x : T) :Unit
  }
  
  val x = new Box[B] {
    def set(b:B) = Console println "B"
  }
  
  val y  = new Box[A] {
    def set(a:A) = Console println "A"
  }
  
  val z  = new Box[C] {
    def set(c:C) = Console println "C"
  }  

  x.set(new A)   <-- Type error

But x.set(new C) is fine, So even though "contravariant parameters are accepted as method parameters" is in fact.但是x.set(new C)很好,所以即使“逆变参数被接受为方法参数”实际上也是如此。 are covariant parameters actually.实际上是协变参数。

You are confusing how contravariance works.您混淆了逆变的工作原理。 x is a Box[B] as such, set accepts values of type B (or any subtype of B because that is what Liskvo says) . x本身就是一个Box[B]set接受类型B的值(或B的任何子类型,因为Liskvo就是这么说的)

However, Box[A] is a subtype of a Box[B] .但是, Box[A]Box[B]子类型 So you could have passed y where x is expected.所以你可以在预期x的地方传递y Because a Box that can store any A can store a B .因为可以存储任何ABox可以存储B
But, a Box that can store only B s can not store and arbitrary A .但是,只能存储BBox不能存储任意A

It looks like this not how it would work and that's from a conceptual stand point: a B is an A but not the other way around.看起来这不是它的工作方式,而是从概念的角度来看: BA ,但反之则不然。

As indicated in thescala doc for variances , contravariant type parameters allow to pass a "super-type" instead of the "sub-type", but this applies to what is used within the body (eg If the "super-type" already has defined what's used) otherwise I guess it just considers the type and we're back to what I explained before.scala doc for variances所示,逆变类型参数允许传递“超类型”而不是“子类型”,但这适用于正文中使用的内容(例如,如果“超类型”已经已经定义了使用的内容)否则我猜它只是考虑类型,我们回到我之前解释的内容。

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

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