Scala 具有协方差的交集类型

Scala 具有协方差的交集类型,scala,generics,dotty,scala-3,Scala,Generics,Dotty,Scala 3,考虑以下因素: trait AA { def children: List[AA] } trait BB { def children: List[BB] } class CC extends AA, BB { override def children: List[AA] & List[BB] = ??? } 当我们在CC中重写子对象时,被重写的方法是顶级方法的合并实体。因此,返回类型List[AA]&List[BB]是有意义的 我不明白的是,下面的代码是

考虑以下因素:

trait AA {
    def children: List[AA]
}

trait BB {
    def children: List[BB]
}

class CC extends AA, BB {
    override def children: List[AA] & List[BB] = ???
}
当我们在
CC
中重写
子对象时,被重写的方法是顶级方法的合并实体。因此,返回类型
List[AA]&List[BB]
是有意义的

我不明白的是,下面的代码是如何编译的

class DD extends AA, BB {
    override def children: List[AA & BB] = ???
}
列表是共同变量,因此(以下是源代码):


要编译DD,
List[AA]&List[BB]
必须是
List[AA&BB]
的子类型。我不明白你为什么这么想,事实上你错了。方法返回类型是协变的,因此情况正好相反:
List[AA&BB]
必须是
List[AA]&List[BB]
的子类型。确实是这样,所以代码很好。

您编写的DD要编译,
List[AA]&List[BB]
必须是
List[AA&BB]
的子类型。我不明白你为什么这么想,事实上你错了。方法返回类型是协变的,因此情况正好相反:
List[AA&BB]
必须是
List[AA]&List[BB]
的子类型。事实确实如此,所以代码是好的。

Matthias Berndt已经回答了
List[AA]和List[BB]C[A&B]
  • 如果
    C
    是逆变的,
    C[A]&C[B]~>C[A | B]
  • 如果
    C
    为非变量,则发出编译错误

  • Matthias Berndt已经回答了
    List[AA]和List[BB]C[A&B]
  • 如果
    C
    是逆变的,
    C[A]&C[B]~>C[A | B]
  • 如果
    C
    为非变量,则发出编译错误

  • 协方差函数返回类型回答它。协方差函数返回类型回答它。
    List[AA & BB] <: List[AA] & List[BB]
    
        val xx: List[AA & BB] = ???
        val yy: List[AA] & List[BB] = ???
        
        val z1: List[AA] & List[BB] = xx
        val z2: List[AA & BB] = yy