gpt4 book ai didi

Scala 协方差和下限我不明白

转载 作者:行者123 更新时间:2023-12-04 02:19:28 24 4
gpt4 key购买 nike

我目前正在学习 Scala,我对方差注释感到困惑,尤其是协方差逆变

所以我做了一些研究并得出了以下示例

 class Box[+T] {

def put[U >: T](x: U): List[U] = {
List(x)
}

}

class Animal {

}

class Cat extends Animal {

}

class Dog extends Animal {

}

var sb: Box[Animal] = new Box[Cat];

所以这表示类 Box 在 T 中是协变的,这意味着 Box[Cat] 是 Box[Animal] 的子类,因为 Cat 是 Animal 的子类。目前我明白这一点。但是当涉及到方法参数时,我的理解就结束了。规范说方法参数不能协变,所以我们必须使用这个下限注释。

让我们看一下方法定义

 def put[U >: T](x: U): List[U] = {
List(x)
}

So [U >: T] says that U must be a superclass of T

尝试下面的代码

  var sb: Box[Animal] = new Box[Cat];
sb.put(new Cat);

按预期工作,但这让我抓狂

  var sb: Box[Animal] = new Box[Cat];
sb.put(1);

从逻辑上讲,将 INT 放入 Box of Animals 中对我来说毫无意义,尽管它是正确的,因为 INT 将被解析为 Any它是 Animal 的父类(super class)。

所以我的问题是

我如何调整 put 方法 只接受子类型的代码动物?我不能使用上限注释

class Box[+T] {

def put[U <: T](x: U): List[U] = {
List(x)
}

}

因为我得到了这个众所周知的错误

covariant type T occurs in contravariant position in type

最佳答案

您可以同时添加下限和上限:

class Box[+T] { def put[U >: T <: Animal](x: U): List[U] = List(x) }

但这不是您想要的,因为您将 Box 的定义连接到 Animal 并且逻辑上没有理由添加这样的上限。

你说:

It logically makes no sense to me to put an INT into a Box of Animals alltough its correct since INT will be resolved to Any which is a superclass of Animal.

你不把一个 Int 放到一个 Box[Animal] 中,现有的盒子是不可变的(并且不可能让它可变,因为定义协方差不允许它)。相反,您会得到一个新类型的框(或者在您的 put 方法的情况下)。如果您的目标只是获得一个 List[Anmial],那么您只需指定:

scala> class Box[+T] { def put[U >: T](x: U): List[U] = List(x) }
defined class Box

scala> var b: Box[Animal] = new Box[Cat]
b: Box[Animal] = Box@23041911

scala> val xs: List[Animal] = b put new Dog
xs: List[Animal] = List(Dog@f8d6ec4)

scala> val xs: List[Animal] = b put 1
<console>:14: error: type mismatch;
found : Int(1)
required: Animal
val xs: List[Animal] = b put 1
^

scala> val xs = b put 1 // this will result in a List[Any]
xs: List[Any] = List(1)

put 方法的定义无需复杂化。

有关为什么需要协变和逆变的更深入的解释,请参阅 this question .

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

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