init(original:items:)
является инициализатором copy . Он берет уже существующий экземпляр структуры и создает новый, идентичный, за исключением того, что он изменяет то, что находится в свойстве items
.
Таким образом, в объявлении протокола init(original: Self, items: [Item])
означает: «Вы передаете мне уже существующий экземпляр того типа, который соответствует мне, протоколу, и мы создадим новый экземпляр, который копирует его при изменении его items
. "
И это именно то, что пример делает. Проще увидеть, соберете ли вы все это вместе, например:
protocol SectionModelType {
associatedtype Item
var items: [Item] { get }
init(original: Self, items: [Item])
}
struct CustomData {
var anInt: Int
var aString: String
var aCGPoint: CGPoint
}
struct SectionOfCustomData {
var header: String
var items: [Item]
}
extension SectionOfCustomData: SectionModelType {
typealias Item = CustomData
init(original: SectionOfCustomData, items: [Item]) {
self = original
self.items = items
}
}
В вашей реализации расширения вам решать, что они сделали: установите self
в original
, это уже существующий объект SectionOfCustomData (который разрешен в инициализаторе структуры), а затем измените его items
. И вы должны делать такие вещи и в таком порядке, потому что если вы этого не сделаете, вы попытаетесь инициализировать объект SectionOfCustomData без установки его свойства header
- тогда как, таким образом, мы гарантируется, что существует уже значение свойства header
, потому что мы начинаем с уже существующего объекта SectionOfCustomData, и вы не можете сделать один без , установив его свойство header
.
Что касается вашего другого беспокойства, то, что это не скомпилируется, если это класс, а не структура: да, вы совершенно правы, но не делайте этого. Это не то, что они сказали делать. Они сказали, сделайте это структурой, и они это имели в виду.