Swift 中的可选协方差如何工作

How does Optional covariance work in Swift

Swift 中 Optional 的协方差如何工作?

假设我写了下面的代码:

var nativeOptionalView: Optional<UIView>
let button = UIButton()
nativeOptionalView = .Some(button)
var nativeOptionalButton = Optional.Some(button)

nativeOptionalView = nativeOptionalButton

它编译并工作得很好。但是,如果我将 MyOptional 定义为

enum MyOptional<T> {
    case Some(T)
    case None
}

并写下:

var myOptionalView: MyOptional<UIView>
let button = UIButton()
myOptionalView = .Some(button)
var myOptionalButton = MyOptional.Some(button)

myOptionalView = myOptionalButton

我收到错误:

error: cannot assign value of type 'MyOptional<UIButton>' to type 'MyOptional<UIView>'

我明白为什么 MyOptional 会出现这个错误,但我不明白为什么 Optional 不会出现这个错误。

虽然我同意可能有一些 "compiler magic" 正在发生,但这可以在您的自定义实现中通过将按钮强制转换为 UIView 来完成,例如

var myOptionalButton = MyOptional.Some(button as UIView)

var myOptionalButton: MyOptional<UIView> = .Some(button)

没有。 Swift 目前不支持自定义协变泛型。

Swift 类型检查器是针对每个表达式的,而不是全局的(如 Haskell)。这个任务是 handled by the Semantic Analysis in lib/Sema. The constraint system then tries to match the types and special cases of covariance are then handled for collections, and optionals.

这是语言设计的决定。你应该能够使用内置的集合类型和可选值做你需要的一切。如果你不是,你可能应该打开雷达。