Swift 模式匹配

Swift pattern matching

在下面的代码中:

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 [=11=].value {
   case let value as Array<Serializable>:
      print("Recognized!")
   default: break
   }
}

如果在

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

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

case let value as Array<Serializable>:会识别,但万一:

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

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

case let value as Array<Serializable>:不会识别,虽然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<Serializable>匹配[Serializable]而不匹配[Owner]

Array<T>T 是不同的类型,因此您不能指望一个人遵守协议会对另一个人产生任何影响。

关于你的例子:

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

此处,您要检查 每个元素 (Element) 的一致性,而不是数组作为其自身类型的一致性。 Element 是一个不同于 Array<Element> 的类型。

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

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

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

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