在 Swift 中,协方差如何用于 Optional
s?
假设我编写以下代码:
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
我收到错误:
错误:无法将类型'
MyOptional<UIButton>
' 的值分配给类型 'MyOptional<UIView>
我明白为什么MyOptional
会发生此错误,我不明白的是为什么Optional
不会发生错误。
它没有。Swift 目前不支持自定义协变泛型。
Swift 类型检查器是按表达式的,而不是全局的(如 Haskell 中)。此任务由 lib/Sema 中的语义分析处理。然后,约束系统尝试匹配类型,然后为集合和可选处理协方差的特殊情况。
这是一个语言设计决策。您应该能够使用内置集合类型和可选功能执行所需的一切。如果你不是,你可能应该打开一个雷达。
虽然我同意可能有一些"编译器魔术"正在发生,但这可以通过将按钮转换为 UIView 在您的自定义实现中实现,例如
var myOptionalButton = MyOptional.Some(button as UIView)
或
var myOptionalButton: MyOptional<UIView> = .Some(button)