Быстрое сопоставление с образцом

В приведенном ниже коде:

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<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

работает, поэтому Свифт признает, что [Owner] является [Serializable], Почему case let value as Array<Serializable> матч [Serializable] но нет [Owner]?

2 ответа

Решение

В Swift протоколы имеют другое и отдельное представление памяти, чем конкретные типы. Таким образом, короткий ответ является массивом Serializable отличается в памяти, чем массив типа, который соответствует Serializableи Swift в настоящее время не имеет механизма приведения между ними.

Более конкретные, мельчайшие подробности в этом докладе WWDC:

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

Array<T> а также T это разные типы, поэтому нельзя ожидать, что соответствие одному протоколу окажет какое-либо влияние на другой.

Что касается вашего примера:

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

Здесь вы проверяете соответствие каждого элемента (Element), а не массив как свой собственный тип. Element это отдельный тип, чем Array<Element>,

Трудно понять, что вы должны делать здесь без дополнительной информации, но я надеюсь, что я ответил, почему вы не получаете ожидаемых результатов.

Другие вопросы по тегам