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