我有一个困扰我的问题。
Scala中的列表是协变(List[+A]
)
假设我们有以下课程:
class A
class B extends A
map
的{{1}}函数采用函数List[B]
但是我也可以使用f: B => C
这是f: A => C
的子类
这完全有道理。
我目前感到困惑的是
f: B => C
函数应仅接受原始函数的超类的函数(因为函数的自变量互斥),不适用于我给出的示例。
我知道我的逻辑有问题,我想启发一下。
答案 0 :(得分:3)
您的错误在于假设gcpStorageManager = new GcpStorageManager() {
@Override
protected Storage getStorageConnection(...) {
return mockedStorage;
}
}
仅应接受属于map(f: A => C)
的超类的函数。
实际上,A => C
将接受map
的子类中的任何函数。
在Scala中,函数参数始终可以是所需类型的子类。
A => C
中A
的协方差仅告诉您,只要需要List[A]
,只要List[A]
,就可以提供List[B]
或者用简单的话来说:B <: A
可以被视为List[B]
的子类。
我整理了一个小例子来解释这两种行为:
List[A]
我希望这会有所帮助。
答案 1 :(得分:0)
您已经怀疑,您在这里混淆了一些事情。
一方面,您有一个List[+A]
,它告诉我们有关List[A]
和{{1} }}。如您所知,List[B]
在A
中是协变的事实仅表示B
是List
时的情况。
另一方面,A
公开了方法List[B] <: List[A]
来更改其“内容”。此方法实际上并不关心B <: A
,而仅关心List
,因此map
的方差在这里无关紧要。让您感到困惑的是,确实有一些子类型需要考虑:List[A]
接受一个参数(在这种情况下为A
,但实际上并不相关),并且像往常一样使用方法和函数,您始终可以将其参数替换为其子类型的任何内容。在您的特定情况下,只要List
,任何map
都可以。这里重要的方差是A => C
,而不是AcceptedType
。