【问题标题】:Swift pattern matching快速模式匹配
【发布时间】:2016-07-27 20:43:39
【问题描述】:

在下面的代码中:

protocol Serializable {
}

struct Owner: Serializable {
   var name: String
}

struct Car: Serializable {
   var owners: [Serializable]
}

let car = Car(owners: [Owner(name: "John"), Owner(name: "Mike")])

Mirror(reflecting: car).children.forEach {
   switch $0.value {
   case let value as Array<Serializable>:
      print("Recognized!")
   default: break
   }
}

如果在

struct Car: Serializable {
   var owners: [Serializable]
}

(所有者变量定义为[Serializable]

case let value as Array&lt;Serializable&gt;: 会识别它,但以防万一:

struct Car: Serializable {
   var owners: [Owner]
}

(所有者变量定义为[Owner]

case let value as Array&lt;Serializable&gt;: 不会识别它,虽然Owner 符合Serializable 协议? 谁能解释一下原因?

我试过了:

extension Array where Element: Serializable {
   var representation: AnyObject {
      return self.map { element in return "String" }
   }
}

let arr: [Owner] = [Owner(name: "John"), Owner(name: "Mike")]
arr.representation

有效,所以 Swift 识别出 [Owner][Serializable],为什么 case let value as Array&lt;Serializable&gt; 匹配 [Serializable] 而不是 [Owner]

【问题讨论】:

  • 你试过case let value where value is Array&lt;Serializable&gt;吗?
  • 它不起作用。工作原理与case let value as Array&lt;Serializable&gt;
  • 有人删除了回复。他提到这不会编译: let arr: [Owner] = [Owner(name: "John"), Owner(name: "Mike")];让 arr2 = arr 为? Array ... 错误:Serializable 不是 Owner 的子类型。

标签: swift generic-constraints


【解决方案1】:

在 Swift 中,协议具有与具体类型不同且独立的内存表示。所以简短的回答是Serializable 的数组在内存中与符合Serializable 的类型的数组不同,Swift 目前没有在两者之间进行转换的机制。

本次 WWDC 演讲中的更多具体细节:

https://developer.apple.com/videos/play/wwdc2016/416/

【讨论】:

  • 谢谢丹尼尔,会检查视频
【解决方案2】:

Array&lt;T&gt;T 是不同的类型,所以你不能指望一个协议的一致性会影响另一个。

关于你的例子:

extension Array where Element: Serializable {
   var representation: AnyObject {
      return self.map { element in return "String" }
   }
}

在这里,您正在检查 每个元素 (Element) 的一致性,而不是 Array 作为它自己的类型。 Element 是与 Array&lt;Element&gt; 不同的类型。

如果没有更多信息,很难知道你应该在这里做什么,但我希望我已经回答了为什么你没有得到预期的结果。

【讨论】:

  • 你是对的 extension Array where Element: Serializable ... Array 和 T 是不同的类型 ...,但令我感到奇怪的是 Swift 认识到 [Owner] 是 [Serializable] 因为Owner 实现了 Serializable 但我不能在 case 语句中使用 [Owner]。
  • Array&lt;Owner&gt;Array&lt;Serializable&gt; 不一样。扩展工作的唯一原因是元素的类型——而不是泛型本身——经过了一致性测试。 OwnerSerializable,仅此而已。
猜你喜欢
  • 2021-11-09
  • 1970-01-01
  • 2014-05-15
  • 2011-09-05
  • 2014-07-15
  • 2012-05-02
  • 1970-01-01
  • 1970-01-01
  • 2021-01-21
相关资源
最近更新 更多