gpt4 book ai didi

scala - 是否可以覆盖类型字段?

转载 作者:行者123 更新时间:2023-12-03 13:58:33 25 4
gpt4 key购买 nike

scala> class C
defined class C

scala> class subC extends C
defined class subC

scala> class A { type T = C}
defined class A

scala> class subA extends A { override type T = subC}
<console>:10: error: overriding type T in class A, which equals C;
type T has incompatible type
class subA extends A { override type T = subC}
^

在上面的示例中,我收到一条错误消息,我无法覆盖类 A 中的类型字段(即使选择的类型 subC 扩展了类 C )。

是否可以覆盖类型字段?如果是的话,上面的例子有什么问题?

最佳答案

你不会说关于类型的“覆盖”,而是缩小它们的界限。

  • type T ... 没有界限
  • type T <: C ... TCC 的子类型(称为上限)
  • type T >: C ... TCC 的父类(super class)型(称为下限)
  • type T = C ... T正是 C (类型别名)

  • 因此,如果 T是 trait A 的类型成员, 和 SubAA 的子类型, 万一 (2) SubA可能会缩小 T到更特殊的子类型 C ,而在情况 (3) 中,它可以将其缩小到 C 的更高父类(super class)型.案例 (1) 对 SubA 没有任何限制。 , 而情况 (4) 意味着 T可以说是“最终的”。

    这会对 T 的可用性产生影响。在 A ——它是否可能作为方法参数的类型或方法的返回类型出现。

    例子:
    trait C { def foo = () }
    trait SubC extends C { def bar = () }

    trait MayNarrow1 {
    type T <: C // allows contravariant positions in MayNarrow1
    def m(t: T): Unit = t.foo // ...like this
    }

    object Narrowed1 extends MayNarrow1 {
    type T = SubC
    }

    object Narrowed2 extends MayNarrow1 {
    type T = SubC
    override def m(t: T): Unit = t.bar
    }

    可以定义方法 mMayNarrow1因为类型 T出现在逆变位置(作为方法参数的类型),因此即使 T 仍然有效被缩小为 MayNarrow1 的子类型(方法体可以将 t 视为类型 C )。

    相比之下, type T = C不可避免地修复 T , 这有点对应于制作方法 final .通过修复 T ,它可以用于协变位置(作为方法的返回类型):
    trait Fixed extends MayNarrow1 {
    type T = C // make that T <: C to see that it won't compile
    final def test: T = new C {}
    }

    您现在可以很容易地看到必须禁止进一步“覆盖” T :
    trait Impossible extends Fixed {
    override type T = SubC

    test.bar // oops...
    }

    为了完整起见,下面是不太常见的下限情况:
    trait MayNarrow2 {
    type T >: SubC // allows covariant positions in MayNarrow2
    def test: T = new SubC {}
    }

    object Narrowed3 extends MayNarrow2 {
    type T = C
    test.foo
    }

    object Narrowed4 extends MayNarrow2 {
    type T = C
    override def test: T = new C {}
    }

    关于scala - 是否可以覆盖类型字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11274729/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com