【问题标题】:How does Optional covariance work in Swift可选协方差如何在 Swift 中工作
【发布时间】:2016-05-20 17:02:58
【问题描述】:

协方差如何在 Swift 中为 Optionals 工作?

假设我写了以下代码:

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&lt;UIButton&gt;”的值分配给类型“MyOptional&lt;UIView&gt;

我理解为什么 MyOptional 会出现此错误,但我不明白为什么 Optional 不会出现此错误。

【问题讨论】:

  • 我怀疑答案是“编译器魔法”。
  • 我很害怕 :/ 在那种情况下,考虑到它是开源的,那么神奇在哪里?
  • 不确定;代码库很大。起点:github.com/apple/swift/…
  • 如果您有兴趣了解它,您可能想在 swift-dev 邮件列表中提出这个问题。
  • 我怀疑这与数组协方差发生的幕后魔术相同,即将Array&lt;UIButton&gt; 分配给Array&lt;UIView&gt;——这些似乎是泛型不变性的例外。跨度>

标签: swift optional covariance


【解决方案1】:

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

Swift 类型检查器是针对每个表达式的,而不是全局的(就像在 Haskell 中一样)。这个任务是handled bylib/Sema中的语义分析。然后约束系统尝试match the types,然后为collectionsoptionals 处理协方差的特殊情况。

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

【讨论】:

    【解决方案2】:

    虽然我同意可能存在一些“编译器魔法”,但这可以在您的自定义实现中通过将按钮转换为 UIView 来完成,例如

    var myOptionalButton = MyOptional.Some(button as UIView)
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-19
      • 2014-07-24
      • 2017-12-10
      • 1970-01-01
      • 2016-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多