gpt4 book ai didi

Scala 协方差和下限类型说明

转载 作者:行者123 更新时间:2023-12-04 00:09:48 25 4
gpt4 key购买 nike

关于使用下限创建新的不可变类型的方法,我试图了解协方差

class ImmutableArray[+T](item: T, existing: List[T] = Nil) {  
private val items = item :: existing

def append[S >: T](value: S) = new ImmutableArray[S](value, items)
}

我了解类型参数 T不能在 append 方法中使用,因为它违反了规则,但如果我说的是 Customer类和子类 Student我还能打字 U Student .

我可以看到这有效,但为什么这不违反规则?如果我有一个 Student 的列表,我可以理解s 然后添加一个 Customer我只能返回 Customer 的列表s 由于不允许 Customer分配给 Student因为它是父类型。但是为什么我可以使用 Student ?

我错过了什么?

谢谢布莱尔

最佳答案

您的类(class)提供 2 个涉及 T 的操作:

  • build
    nextImmutableArray = new ImmutableArray(nextT, priorImmutableArray)

    由于此操作,类型参数 T 必须是协变的:+T。这允许您使用设置为类型对象(T 或 T 的子类型)的参数进行构造。

    想一想:通过包含一个 Valencia Orange 来构造一个 Oranges 数组是有效的。
  • 组合
    nextImmutableArray.append(newItemTorAncestor)

    此方法不会附加到您的数据结构。它需要两个独立的元素(你的数组实例 这个 和一个额外的对象),并将它们组合在一个新构造的数组中。您可以考虑将方法名称更改为 appendIntoCopy .更好的是,您可以使用名称 + .但是为了最正确并与 Scala 约定保持一致,最好的名称是 :+ .

    当你问一个特定的问题时,我为什么要胡扯关于“随机”方法的名称???

    因为该方法的精确性质决定了返回的数据结构是否 (a) 与 T 非变异 (b) 与 T 共变 (c) 与 T 逆变。
  • 开始于: ImmutableArray[T] - 包含类型 T(或子类型)
  • 结合:S 类型的对象。
  • 结果:ImmutableArray[S]
  • 如果允许 S 是 T 的适当子类型(超出 T 本身),则新数组不能包含 T 类型的原始元素!
  • 如果 S 是 T 类型或 T 的父类(super class)型,那么一切都很好 - 可以包含原始元素,加上新元素!

  • 当您组合数组和元素时,新创建的数据结构必须有一个类型参数,它是共同祖先类型的父类(super class)型。否则它不能包含原始元素。通常,当您执行“a :+ b”时,其中 A 是一个 Array[A] 并且 b 是 B 类型,结果数据结构是 Array[Some_SuperType_Of_Both_A_and_B]。

    想一想:如果我从一系列橙子开始,然后添加一个柠檬,我最终会得到一系列柑橘类水果(不是橙子、脐橙或柠檬)。

    方法规则(严格输入,适应输出):
  • a) 输入参数提供了要插入的元素(变异):协变
  • a) 输出参数从数据结构返回一个元素:逆变器
  • c) 输出参数,合并后返回数据结构:逆变器
  • c) 使用类型作为下限: “翻转”方差 (“与 T 反变”=“与 S 共变,具有下限 T”)

  • 在追加的情况下:以 T 开头,输出数据结构 = T 的逆变,类型 S 使用 T 作为下限,因此输入参数 = 与 S 的协变。这意味着如果 T1 是 T2 的子类型,则ImmutableArray[T1] 是 ImmutableArray[T2] 的一个子类型,它可以在任何需要后者的地方替换,所有方法都遵循 Liskov 的替换原则。

    关于Scala 协方差和下限类型说明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19428376/

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