给出以下类定义
class X [+ T] {
def get [U>:T] (default:U)
:U
}
为什么方法def get[U>:T]
中的T(默认值:U)处于协方差位置
给出以下类定义
class X [-T] {
def get [U<:T] (default:U)
:U
}
为什么方法def get[U<:T]
中的T(默认值:U)处于协方差位置
答案 0 :(得分:1)
很难回答&#34;为什么?&#34;问题没有你提供更多细节,但我会尝试。我认为你的问题确实是&#34;为什么U
上的类型限制没有被反转?&#34;。简短的回答:因为这是类型安全的,并且涵盖了一些其他方面没有涉及的情况。
您的第一个示例可能受Option[T]
及其getOrElse
方法的启发。虽然我不确定为什么任何人需要getOrElse
U
与T
不同,但逻辑为什么类型限制只能U>:T
对我来说是显而易见的。我们假设您有3个类:C
继承B
,继承A
并且您有Option[B]
。如果您的default
值已经B
或C
,那么除了U
= T
之外,您不需要任何其他内容,因此签名更简单,无需额外的通用{{} 1}}就足够了。如果您的某种类型不是U
的子类型(例如getOrElse
),那么您无法将默认值传递给B
方法的唯一情况就是如此。让我们暂时延长这个签名
A
类型def getOrElse[U, R](default:U): R
,U
和T
应该如何相关?显然,R
应该是R
和U
的常见超类型,因为它应该能够同时包含T
和T
。然而,这样的定义将是一种矫枉过正。首先,拥有一个与U
无关的类型的默认值真的很奇怪。其次,即使是如此奇怪的情况,您(和编译器)仍然可以计算一个常见的超类型并将其分配给一些新的T
= U'
。因此,您不需要R'
,但添加R
会增加一些灵活性(至少在理论上)。但是U
仍然必须是U
的超类型,因为它也是返回类型。
总而言之:添加T
与U
将
U<:T
作为结果类型,则U
因为结果类型无法保留U
)T
作为结果类型将不会扩展此方法的适用性,即不允许任何不使用T
编译的代码使用此附加U
进行编译。 但是将U
添加到U
将允许更多代码实际上是类型安全的编译,例如(是的,愚蠢的例子,但正如我所说,我不知道任何现实生活实施例):
U>:T