рд╕реНрд╡рд┐рдлреНрдЯ рдореЗрдВ рдЬреЗрдирд░рд┐рдХ рдХреА рд╢рдХреНрддрд┐ред рднрд╛рдЧ реи

рд╢реБрдн рджреЛрдкрд╣рд░, рджреЛрд╕реНрддреЛрдВред рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдкрд╛рдареНрдпрдХреНрд░рдо "iOS рдбреЗрд╡рд▓рдкрд░" рдХреЗ рдЫрд╛рддреНрд░реЛрдВ рдХреЗ рд▓рд┐рдП ред рдПрдбрд╡рд╛рдВрд╕реНрдб рдХреЛрд░реНрд╕ тАЭ, рд╣рдордиреЗтАЬ рд╕реНрд╡рд┐рдлреНрдЯ рдореЗрдВ рдЬреЗрдирд░рд┐рдХ рдХреА рд╢рдХреНрддрд┐ тАЭрд▓реЗрдЦ рдХреЗ рджреВрд╕рд░реЗ рднрд╛рдЧ рдХрд╛ рдЕрдиреБрд╡рд╛рдж рддреИрдпрд╛рд░ рдХрд┐рдпрд╛ред





рд╕рдВрдмрдВрдзрд┐рдд рдкреНрд░рдХрд╛рд░, рдЬрд╣рд╛рдВ рдЦрдВрдб, рд╕рджрд╕реНрдпрддрд╛, рдФрд░ рдмрд╣реБрдд рдХреБрдЫ ...

рд▓реЗрдЦ "рд╕реНрд╡рд┐рдлреНрдЯ рдореЗрдВ рдЬреЗрдирд░рд┐рдХ рдХреА рд╢рдХреНрддрд┐ред рднрд╛рдЧ 1 " рд╕рд╛рдорд╛рдиреНрдп рдХрд╛рд░реНрдп, рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рдХрд╛рд░ рдФрд░ рдкреНрд░рддрд┐рдмрдВрдзреЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдпрджрд┐ рдЖрдк рдПрдХ рд╢реБрд░реБрдЖрддреА рд╣реИрдВ, рддреЛ рдореИрдВ рдЖрдкрдХреЛ рд╕рд▓рд╛рд╣ рджреВрдВрдЧрд╛ рдХрд┐ рдЖрдк рдмреЗрд╣рддрд░ рд╕рдордЭ рдХреЗ рд▓рд┐рдП рдкрд╣рд▓реЗ рднрд╛рдЧ рдХреЛ рдкрдврд╝реЗрдВред

рдХрд┐рд╕реА рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╕рдордп, рдкрд░рд┐рднрд╛рд╖рд╛ рдХреЗ рд╣рд┐рд╕реНрд╕реЗ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рдпрд╛ рдЕрдзрд┐рдХ рд╕рдВрдмрдВрдзрд┐рдд рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдШреЛрд╖рд┐рдд рдХрд░рдирд╛ рдХрднреА-рдХрднреА рдЙрдкрдпреЛрдЧреА рд╣реЛрддрд╛ рд╣реИред рд╕рдВрдмрдВрдзрд┐рдд рдкреНрд░рдХрд╛рд░ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЗ рднрд╛рдЧ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рд╕реНрдЯрдм рдирд╛рдо рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рд╕рдВрдмрдВрдзрд┐рдд рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкреНрд░рдХрд╛рд░ рдХреЛ рддрдм рддрдХ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдЬрдм рддрдХ рдХрд┐ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рди рдХрд┐рдпрд╛ рдЬрд╛рдПред рд╕рдВрдмрджреНрдз рдкреНрд░рдХрд╛рд░ рдХреЛ associatedtype рдХреАрд╡рд░реНрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рд╣рдо рдЙрд╕ рд╕реНрдЯреИрдХ рдХреЗ рд▓рд┐рдП рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕реЗ рд╣рдордиреЗ рдкрд╣рд▓реЗ рднрд╛рдЧ рдореЗрдВ рдмрдирд╛рдпрд╛ рдерд╛ред

 protocol Stackable { associatedtype Element mutating func push(element: Element) mutating func pop() -> Element? func peek() throws -> Element func isEmpty() -> Bool func count() -> Int subscript(i: Int) -> Element { get } } 

Stackable рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдЖрд╡рд╢реНрдпрдХ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдХрд┐рд╕реА рднреА рд╕реНрдЯреИрдХ рдХреЛ рдкреНрд░рджрд╛рди рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ рдЬреЛ Stackable рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЗ рдЕрдиреБрд░реВрдк рд╣реИ, рд╡рд╣ рдЙрд╕ рд╕реНрдЯреЛрд░ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рд╕реНрдЯреИрдХ рдореЗрдВ рдХреЗрд╡рд▓ рд╕рд╣реА рдкреНрд░рдХрд╛рд░ рдХреЗ рддрддреНрд╡ рдЬреЛрдбрд╝реЗ рдЬрд╛рддреЗ рд╣реИрдВ, рдФрд░ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдХрд┐рд╕ рдкреНрд░рдХрд╛рд░ рдХреЗ рддрддреНрд╡ рдЗрд╕рдХреА рдЙрдкрдзрд╛рд░рд╛ рджреНрд╡рд╛рд░рд╛ рд╡рд╛рдкрд╕ рдХрд┐рдП рдЧрдП рд╣реИрдВред

рдЪрд▓реЛ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рд╣рдорд╛рд░реЗ рд╕реНрдЯреИрдХ рдХреЛ рдмрджрд▓рддреЗ рд╣реИрдВ:

 enum StackError: Error { case Empty(message: String) } protocol Stackable { associatedtype Element mutating func push(element: Element) mutating func pop() -> Element? func peek() throws -> Element func isEmpty() -> Bool func count() -> Int subscript(i: Int) -> Element { get } } public struct Stack<T>: Stackable { public typealias Element = T var array: [T] = [] init(capacity: Int) { array.reserveCapacity(capacity) } public mutating func push(element: T) { array.append(element) } public mutating func pop() -> T? { return array.popLast() } public func peek() throws -> T { guard !isEmpty(), let lastElement = array.last else { throw StackError.Empty(message: "Array is empty") } return lastElement } func isEmpty() -> Bool { return array.isEmpty } func count() -> Int { return array.count } } extension Stack: Collection { public func makeIterator() -> AnyIterator<T> { var curr = self return AnyIterator { curr.pop() } } public subscript(i: Int) -> T { return array[i] } public var startIndex: Int { return array.startIndex } public var endIndex: Int { return array.endIndex } public func index(after i: Int) -> Int { return array.index(after: i) } } extension Stack: CustomStringConvertible { public var description: String { let header = "***Stack Operations start*** " let footer = " ***Stack Operation end***" let elements = array.map{ "\($0)" }.joined(separator: "\n") return header + elements + footer } } var stack = Stack<Int>(capacity: 10) stack.push(element: 1) stack.pop() stack.push(element: 3) stack.push(element: 4) print(stack) 


рд╕рдВрдмрдВрдзрд┐рдд рдкреНрд░рдХрд╛рд░ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдореМрдЬреВрджрд╛ рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдирд╛


рдЖрдк рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХрд╛ рдкрд╛рд▓рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдореМрдЬреВрджрд╛ рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

 protocol Container { associatedtype Item mutating func append(_ item: Item) var count: Int { get } subscript(i: Int) -> Item { get } } extension Array: Container {} 

рд╕рдВрдмрдВрдзрд┐рдд рдкреНрд░рдХрд╛рд░ рд╕реЗ рдмрд╛рдзрд╛рдУрдВ рдХреЛ рдЬреЛрдбрд╝рдирд╛:


рдЖрдк рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдореЗрдВ рд╕рдВрдмрдВрдзрд┐рдд рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреНрд░рддрд┐рдмрдВрдз рдХреЛ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╕рдВрдмрдВрдзрд┐рдд рдкреНрд░рдХрд╛рд░ рдЗрди рдкреНрд░рддрд┐рдмрдВрдзреЛрдВ рдХрд╛ рдЕрдиреБрдкрд╛рд▓рди рдХрд░рддреЗ рд╣реИрдВред
Stackable рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЛ рдмрджрд▓рддреЗ рд╣реИрдВред

 protocol Stackable { associatedtype Element: Equatable mutating func push(element: Element) mutating func pop() -> Element? func peek() throws -> Element func isEmpty() -> Bool func count() -> Int subscript(i: Int) -> Element { get } } 

рдЕрдм рд╕реНрдЯреИрдХ рддрддреНрд╡ рдХрд╛ рдкреНрд░рдХрд╛рд░ Equatable рдореЗрд▓ Equatable рдЪрд╛рд╣рд┐рдП, рдЕрдиреНрдпрдерд╛ рдПрдХ рд╕рдВрдХрд▓рди-рд╕рдордп рддреНрд░реБрдЯрд┐ рд╣реЛрдЧреАред

рдкреБрдирд░рд╛рд╡рд░реНрддреА рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдкреНрд░рддрд┐рдмрдВрдз:


рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдЕрдкрдиреА рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

 protocol SuffixableContainer: Container { associatedtype Suffix: SuffixableContainer where Suffix.Item == Item func suffix(_ size: Int) -> Suffix } 

Suffix рдХреА рджреЛ рд╕реАрдорд╛рдПрдБ рд╣реИрдВ: рдЗрд╕реЗ SuffixableContainer рдкреНрд░реЛрдЯреЛрдХреЙрд▓ (рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдпрд╣рд╛рдБ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ) рдХреЗ рд╕рд╛рде рдкрд╛рд▓рди рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рдЗрд╕рдХреЗ Item рдкреНрд░рдХрд╛рд░ рдХреЛ рдХрдВрдЯреЗрдирд░ рдХреЗ Item рдкреНрд░рдХрд╛рд░ рд╕реЗ рдореЗрд▓ рдЦрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдЗрд╕ рд╡рд┐рд╖рдп Protocol Sequence рд╕реНрдкрд╖реНрдЯ Protocol Sequence рдореЗрдВ рд╕реНрд╡рд┐рдлреНрдЯ рдорд╛рдирдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рдПрдХ рдЕрдЪреНрдЫрд╛ рдЙрджрд╛рд╣рд░рдг рд╣реИред

рдкреБрдирд░рд╛рд╡рд░реНрддреА рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреА рд╕реАрдорд╛рдУрдВ рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡: https://github.com/apple/swift-evolution/blob/master/proposals/0157-recursive-protocol-constraints.md

рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рдХрд╛рд░ рдХреЗ рдПрдХреНрд╕рдЯреЗрдВрд╢рди:


рдЬрдм рдЖрдк рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╕рдордп рдкреНрд░рдХрд╛рд░ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рд╕реВрдЪреА рдХрд╛ рд╡рд░реНрдгрди рдирд╣реАрдВ рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рд╕реНрд░реЛрдд рдкрд░рд┐рднрд╛рд╖рд╛ рд╕реЗ рдкреНрд░рдХрд╛рд░ рдкреИрд░рд╛рдореАрдЯрд░ рдХреА рдПрдХ рд╕реВрдЪреА рд╡рд┐рд╕реНрддрд╛рд░ рдирд┐рдХрд╛рдп рдореЗрдВ рдЙрдкрд▓рдмреНрдз рд╣реИ, рдФрд░ рд╕реНрд░реЛрдд рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рдирд╛рдо рдХрд╛ рдЙрдкрдпреЛрдЧ рд╕реНрд░реЛрдд рдкрд░рд┐рднрд╛рд╖рд╛ рд╕реЗ рдкреНрд░рдХрд╛рд░ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред


 extension Stack { var topItem: Element? { return items.isEmpty ? nil : items[items.count - 1] } } 

рдЬреЗрдиреЗрд░рд┐рдХ рдЬрд╣рд╛рдВ рдХреНрд▓реЙрдЬ


рд╕рдВрдмрдВрдзрд┐рдд рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП, рдпрд╣ рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реИред рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХрд╛ рд╡рд░реНрдгрди рдЬреЗрдиреЗрд░рд┐рдХ рджреНрд╡рд╛рд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рдЦрдВрдб ред рдЬреЗрдиреЗрд░рд┐рдХ where рдХреНрд▓реЙрдЬ рдЖрдкрдХреЛ рдпрд╣ рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдХрд┐ рд╕рдВрдмрдВрдзрд┐рдд рдкреНрд░рдХрд╛рд░ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЗ рдЕрдиреБрд░реВрдк рд╣реИ рдпрд╛ рдХрд┐ рдХреБрдЫ рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рдФрд░ рд╕рдВрдмрдВрдзрд┐рдд рдкреНрд░рдХрд╛рд░ рд╕рдорд╛рди рд╣реИрдВред рдЬреЗрдиреЗрд░рд┐рдХ where рдХреНрд▓реЙрдЬ where рдХреАрд╡рд░реНрдб рд╕реЗ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ, рдЙрд╕рдХреЗ рдмрд╛рдж рд╕рдВрдмрдВрдзрд┐рдд рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдмрд╛рдзрд╛рдУрдВ рдпрд╛ рдкреНрд░рдХрд╛рд░реЛрдВ рдФрд░ рд╕рдВрдмрдВрдзрд┐рдд рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдмреАрдЪ рд╕рдорд╛рдирддрд╛ рдХрд╛ рд╕рдВрдмрдВрдз рд╣реЛрддрд╛ рд╣реИред рдЬреЗрдиреЗрд░рд┐рдХ where рдХреНрд▓реЙрдЬ рдЯрд╛рдЗрдк рдпрд╛ рдлрд╝рдВрдХреНрд╢рди рдмреЙрдбреА рдХреЗ рдЙрджреНрдШрд╛рдЯрди рдмреНрд░реЗрд╕ рд╕реЗ рдареАрдХ рдкрд╣рд▓реЗ рд▓рд┐рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИред

 func allItemsMatch<C1: Container, C2: Container> (_ someContainer: C1, _ anotherContainer: C2) -> Bool where C1.Item == C2.Item, C1.Item: Equatable { } 

рдЬрд╣рд╛рдВ рд╕рд╛рдорд╛рдиреНрдп рдкрд░рд┐рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХреНрд╕рдЯреЗрдВрд╢рди


рдЖрдк рдЬреЗрдиреЗрд░рд┐рдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ where рд╡рд┐рд╕реНрддрд╛рд░ рдХреЗ рд╣рд┐рд╕реНрд╕реЗ рдХреЗ рд░реВрдк рдореЗрдВ рдЦрдВрдбред рдирд┐рдореНрди рдЙрджрд╛рд╣рд░рдг isTop (_ :) рд╡рд┐рдзрд┐ рдХреЛ рдЬреЛрдбрд╝рдХрд░ рдкрд┐рдЫрд▓реЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреА рд╕рдордЧреНрд░ Stack рд╕рдВрд░рдЪрдирд╛ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рддрд╛ рд╣реИред

 extension Stack where Element: Equatable { func isTop(_ item: Element) -> Bool { guard let topItem = items.last else { return false } return topItem == item } } 

рдПрдХреНрд╕рдЯреЗрдВрд╢рди isTop (_ :) рд╡рд┐рдзрд┐ рдХреЛ рдХреЗрд╡рд▓ рддрднреА рдЬреЛрдбрд╝рддрд╛ рд╣реИ рдЬрдм рд╕реНрдЯреИрдХ рд╕рдорд░реНрдерди рдкрд░ рдЖрдЗрдЯрдо рд╕рдорд╛рди рд╣реЛред рдЖрдк рдЙрд╕ рдЬреЗрдирд░рд┐рдХ рдХрд╛ рднреА рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ where рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЗ рд╕рд╛рде рдХреНрд▓реЙрдЬ рд╣реИред рдЖрдк рдЙрдиреНрд╣реЗрдВ рдЕрд▓реНрдкрд╡рд┐рд░рд╛рдо where рдЕрд▓рдЧ where рдХрдИ рдЖрд╡рд╢реНрдпрдХрддрд╛рдПрдВ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред

рдЬреЗрдиреЗрд░рд┐рдХ рдХреНрд▓реЙрдЬ рдХреЗ рд╕рд╛рде рд╕рдВрдмрджреНрдз рдкреНрд░рдХрд╛рд░ рдЬрд╣рд╛рдВ:


рдЖрдк рдЙрд╕ рдЬреЗрдиреЗрд░рд┐рдХ рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ where рд╕рдВрдмрджреНрдз рдкреНрд░рдХрд╛рд░ рдореЗрдВ рдХреНрд▓реЙрдЬрд╝ рд╣реИред

 protocol Container { associatedtype Item mutating func append(_ item: Item) var count: Int { get } subscript(i: Int) -> Item { get } associatedtype Iterator: IteratorProtocol where Iterator.Element == Item func makeIterator() -> Iterator } 

рдПрдХ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЗ рд▓рд┐рдП рдЬреЛ рджреВрд╕рд░реЗ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ рд╣реИ, рдЖрдк рдЬреЗрдиреЗрд░рд┐рдХ where рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдШреЛрд╖рдгрд╛ рдореЗрдВ рдЦрдВрдб рд╕рд╣рд┐рдд рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдмрдВрдзреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдмрд╛рдзрд╛ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдирд┐рдореНрди рдХреЛрдб рдПрдХ ComparableContainer рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреА рдШреЛрд╖рдгрд╛ рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕рдХреЗ Item Comparable Item рд╕рдорд░реНрдерди Item рд▓рд┐рдП Item рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ:

 protocol ComparableContainer: Container where Item: Comparable { } 

рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рдХрд╛рд░ рдХреЗ рдЙрдкрдирд╛рдо:


рдЯрд╛рдЗрдк рдЙрд░реНрдл тАЛтАЛрдореЗрдВ рд╕рд╛рдорд╛рдиреНрдп рдкреИрд░рд╛рдореАрдЯрд░ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рдЕрднреА рднреА рдПрдХ рдЙрдкрдирд╛рдо (рдпрд╛рдиреА, рдпрд╣ рдПрдХ рдирдП рдкреНрд░рдХрд╛рд░ рдХрд╛ рдкрд░рд┐рдЪрдп рдирд╣реАрдВ рджреЗрдЧрд╛) рд░рд╣реЗрдЧрд╛ред

 typealias StringDictionary<Value> = Dictionary<String, Value> var d1 = StringDictionary<Int>() var d2: Dictionary<String, Int> = d1 // okay: d1 and d2 have the same type, Dictionary<String, Int> typealias DictionaryOfStrings<T : Hashable> = Dictionary<T, String> typealias IntFunction<T> = (T) -> Int typealias Vec3<T> = (T, T, T) typealias BackwardTriple<T1,T2,T3> = (T3, T2, T1) 

рдЗрд╕ рддрдВрддреНрд░ рдореЗрдВ, рдкреНрд░рдХрд╛рд░ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд рдкреНрд░рддрд┐рдмрдВрдзреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдРрд╕рд╛ рдХреЛрдб рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛:

 typealias ComparableArray<T where T : Comparable> = Array<T> 

рдЬреЗрдиреЗрд░рд┐рдХ рд╕реБрдкрд░рд╕реНрдХреНрд░рд┐рдкреНрдЯ


рд╕рджрд╕реНрдпрддрд╛ рдЬреЗрдиреЗрд░рд┐рдХ рддрдВрддреНрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреА рд╣реИ рдФрд░ рдЬреЗрдиреЗрд░рд┐рдХ рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд░ рд╕рдХрддреА рд╣реИ where рдХреНрд▓реЙрдЬред рдЖрдк subscript рдмрд╛рдж рдПрдВрдЧрд▓ рдмреНрд░реИрдХреЗрдЯреНрд╕ рдореЗрдВ рдЯрд╛рдЗрдк рдирд╛рдо рд▓рд┐рдЦреЗрдВ, рдФрд░ рдЬреЗрдиреЗрд░рд┐рдХ рд▓рд┐рдЦреЗрдВ where рд╕рдмрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдмреЙрдбреА рдХреЗ рдУрдкрдирд┐рдВрдЧ рдмреНрд░реЗрд╕ рд╕реЗ рддреБрд░рдВрдд рдкрд╣рд▓реЗ рдХреНрд▓реЙрдЬ рд╣реЛред

 extension Container { subscript<Indices: Sequence>(indices: Indices) -> [Item] where Indices.Iterator.Element == Int { var result = [Item]() for index in indices { result.append(self[index]) } return result } } 

рд╕рд╛рдорд╛рдиреНрдп рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛


рдЬреЗрдиреЗрд░рд┐рдХ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдХрдВрдкрд╛рдЗрд▓рд░ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рдЬреИрд╕реЗ рдХрд┐ рдЗрдВрдЯ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рдХрд╛рд░ рдпрд╛ рдлрд╝рдВрдХреНрд╢рди, рдЬреИрд╕реЗ рд╕реНрдЯреИрдХ < рдЯреА > рдХреНрд▓реЛрди рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рд╡рд┐рд╢реЗрд╖ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдЗрдВрдЯ рдХреЗ рд▓рд┐рдП рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬрдмрдХрд┐ рд╡рд╣ рд╕рдм рдЬреЛ рдЕрддрд┐рд╢реНрдпреЛрдХреНрддрд┐рдкреВрд░реНрдг рд╣реИ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рд╕рдВрдХрд▓рди рд╕рдордп рдкрд░ рдЯрд╛рдЗрдк рддрд░реНрдХреЛрдВ рдХреЗ рд╕рд╛рде рдкреНрд░рдХрд╛рд░ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдмрджрд▓рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ ред

рдЗрди рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рд╕рд╛рдорд╛рдиреНрдп рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рджреЗрдХрд░, рд╣рдо рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдиреЗ рдкрд░ рд╡рд░реНрдЪреБрдЕрд▓ рдбрд┐рд╕реНрдкреИрдЪрд┐рдВрдЧ, рдЗрдирд▓рд╛рдЗрди рдХреЙрд▓ рдХреА рд▓рд╛рдЧрдд рдХреЛ рд╕рдорд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рдгрд╛рд▓реА рдХреЗ рдУрд╡рд░рд╣реЗрдб рдХреЛ рд╕рдорд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рд╕рдВрдЪрд╛рд▓рдХ рдЕрдзрд┐рднрд╛рд░


рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рдХрд╛рд░ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдСрдкрд░реЗрдЯрд░реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдПрдХ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред

 func ==<T: Equatable>(lhs: Matrix<T>, rhs: Matrix<T>) -> Bool { return lhs.array == rhs.array } 


рдЬреЗрдирд░рд┐рдХ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рджрд┐рд▓рдЪрд╕реНрдк рдмрд╛рдд


рдЖрдк рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рд╕реНрдерд┐рд░ рд╕рдВрдЧреНрд░рд╣реАрдд рд╕рдВрдкрддреНрддрд┐ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХреНрдпреЛрдВ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ?

рдЗрд╕рдХреЗ рд▓рд┐рдП рдкреНрд░рддреНрдпреЗрдХ рд╡реНрдпрдХреНрддрд┐рдЧрдд рдЬреЗрдиреЗрд░рд┐рдХ (T) рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдХреЗ рд▓рд┐рдП рдЧреБрдгреЛрдВ рдХреЗ рдПрдХ рдЕрд▓рдЧ рднрдВрдбрд╛рд░рдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред

рдЧрд╣рди рдЕрдзреНрдпрдпрди рдХреЗ рд▓рд┐рдП рд╕рдВрд╕рд╛рдзрди:


https://github.com/apple/swift/blob/master/docs/Generics.rst
https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md
https://developer.apple.com/videos/play/wwdc2018/406/
https://www.youtube.com/watch?v=ctS8FzqcRug
https://medium.com/@vhart/protocols-generics-and-existential-containers-wait-what-e2e698262ab1


рд╡рд╣ рд╕рдм рд╣реИред рдХреЛрд░реНрд╕ рдкрд░ рдорд┐рд▓рддреЗ рд╣реИрдВ ред

Source: https://habr.com/ru/post/hi463789/


All Articles