代码之家  ›  专栏  ›  技术社区  ›  AZ_

scala方差概念,为什么不编译

  •  0
  • AZ_  · 技术社区  · 6 年前

    我是斯卡拉的笨蛋,所以请不要投反对票。

    class MyClass extends AnyRef
    class MySubClass extends MyClass
    
    val af0: (Seq[_]) => Boolean = (s) ⇒ { s eq null }
    
    val f4: (MySubClass) => Boolean = (s) => { s eq null }
    
    val af2: (List[_]) => Boolean = af0 //(Line 1)
    val f7: MyClass => Boolean = f4 //(Line 2)
    

    为什么行(1)编译而行(2)不编译?对我来说,它们都和序列是列表的子类型一样。如何使其工作?比如说第一行?

    https://docs.scala-lang.org/tutorials/FAQ/collections.html [列出对象层次结构]

    2 回复  |  直到 6 年前
        1
  •  3
  •   Suma    6 年前

    contravariance

    class HisSubClass extends MyClass
    
    val his = new HisSubClass 
    f7(his) // his is accepted as MyClass
    

    f4 MySubClass

    Seq List

    val af2: (List[_]) => Boolean = af0
    

    val aff0: (MyClass) => Boolean = (s) ⇒ { s eq null }
    val aff2: (MySubClass) => Boolean = aff0
    

    MyClass

    f7

        2
  •  2
  •   Duelist    6 年前
    val f7:myclass=>boolean=s=>s eq空
    val f44:(mySubclass)=>布尔值=f7
    
    
    

    您可以在这里找到差异的解释。

    函数1[MyClass,Boolean]
    ,但第一个类型参数Function1是反变的,参见API文件:

    trait Function1[-T1, +R] extends AnyRef

    但它允许你这样做:

    val f7: MyClass => Boolean = s => s eq null 
    val f44: (MySubClass) => Boolean = f7
    

    你可以找到差异的解释here.