Download - Swift School #2
![Page 1: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/1.jpg)
Swift Школа
Сергей Пронин Empatika
![Page 2: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/2.jpg)
План
• Перечисления
• Generic
• Протоколы
• Optionals
![Page 3: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/3.jpg)
Перечисления
![Page 4: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/4.jpg)
Перечисления Enumerations
• Полноценный тип (наравне с классами)
• Обладает свойствами класса конструкторы, вычисляемые свойства, динамические методы (у объектов)
• Поддерживает расширения (extensions - категории) и протоколы (protocols)
![Page 5: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/5.jpg)
enum Animal { // значения case Dog case Cat case Fish case Robot }
enum LazyAnimal { // Одного 'case' достаточно case Dog, Cat, Fish, Robot }
По умолчанию значениям не присваиваются Int эквиваленты
Каждое значение имеет тип своего перечисления
![Page 6: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/6.jpg)
let pet = Animal.Dog switch pet { case .Dog: println("WOF-WOF") case .Cat: println("MEOW") case .Fish: println("???") case .Robot: println("Death to humans!") }
![Page 7: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/7.jpg)
“Ассоциированные” значения
• Каждый объект перечисления может содержать объект другого типа в качестве соответствия
• В таком случае их типы могут быть разными
• Позволяет “ассоциировать” любую информацию
![Page 8: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/8.jpg)
enum Barcode { case UPCA(Int, Int, Int) case PDF417(String) }
var productBarcode = Barcode.UPCA(1, 2, 3) productBarcode = .PDF417("ABCD")
![Page 9: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/9.jpg)
Ассоциированные значения доступны в switch-case конструкции
![Page 10: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/10.jpg)
Ассоциированные значения доступны в switch-case конструкции
switch productBarcode {
![Page 11: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/11.jpg)
Ассоциированные значения доступны в switch-case конструкции
switch productBarcode {case .UPCA(let system, let ident, let check):
![Page 12: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/12.jpg)
Ассоциированные значения доступны в switch-case конструкции
switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")
![Page 13: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/13.jpg)
Ассоциированные значения доступны в switch-case конструкции
switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")case .PDF417(let code):
![Page 14: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/14.jpg)
Ассоциированные значения доступны в switch-case конструкции
switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")case .PDF417(let code): println("PDF417 with value of \(code).")
![Page 15: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/15.jpg)
Ассоциированные значения доступны в switch-case конструкции
switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")case .PDF417(let code): println("PDF417 with value of \(code).")}
![Page 16: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/16.jpg)
Ассоциированные значения доступны в switch-case конструкции
switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")case .PDF417(let code): println("PDF417 with value of \(code).")}
![Page 17: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/17.jpg)
Ассоциированные значения доступны в switch-case конструкции
switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")case .PDF417(let code): println("PDF417 with value of \(code).")}
// Syntax sugar
![Page 18: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/18.jpg)
Ассоциированные значения доступны в switch-case конструкции
switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")case .PDF417(let code): println("PDF417 with value of \(code).")}
// Syntax sugarswitch productBarcode {
![Page 19: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/19.jpg)
Ассоциированные значения доступны в switch-case конструкции
switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")case .PDF417(let code): println("PDF417 with value of \(code).")}
// Syntax sugarswitch productBarcode {case let .UPCA(system, ident, check):
![Page 20: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/20.jpg)
Ассоциированные значения доступны в switch-case конструкции
switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")case .PDF417(let code): println("PDF417 with value of \(code).")}
// Syntax sugarswitch productBarcode {case let .UPCA(system, ident, check): println("UPCA with value of \(system), \(ident), \(check).")
![Page 21: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/21.jpg)
Ассоциированные значения доступны в switch-case конструкции
switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")case .PDF417(let code): println("PDF417 with value of \(code).")}
// Syntax sugarswitch productBarcode {case let .UPCA(system, ident, check): println("UPCA with value of \(system), \(ident), \(check).")case let .PDF417(code):
![Page 22: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/22.jpg)
Ассоциированные значения доступны в switch-case конструкции
switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")case .PDF417(let code): println("PDF417 with value of \(code).")}
// Syntax sugarswitch productBarcode {case let .UPCA(system, ident, check): println("UPCA with value of \(system), \(ident), \(check).")case let .PDF417(code): println("PDF417 with value of \(code).")
![Page 23: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/23.jpg)
Ассоциированные значения доступны в switch-case конструкции
switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")case .PDF417(let code): println("PDF417 with value of \(code).")}
// Syntax sugarswitch productBarcode {case let .UPCA(system, ident, check): println("UPCA with value of \(system), \(ident), \(check).")case let .PDF417(code): println("PDF417 with value of \(code).")}
![Page 24: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/24.jpg)
“Замещающие” значения
• Каждый объект перечисления может быть сопоставлен с объектом другого типа
• “Замещающие” значения не меняются (в отличие от “ассоциированных”
• Допустимые типы: Character, String, Double, Float, Int*
![Page 25: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/25.jpg)
// для Int работает auto-increment enum Number: Int { case One = 1, Two, Three, Four, Five, Six, Seven, Eight, FortyTwo = 42 }
enum Letter: Character { case A = "a" case B = "b" case C = "c" }
let answerToTheAllQuestions = Number.FortyTwo answerToTheAllQuestions.toRaw()
let twoOnTwo = Number.fromRaw(2 * 2) twoOnTwo?.toRaw()
![Page 26: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/26.jpg)
*// свой тип для перечислений final class CustomRawType: IntegerLiteralConvertible, Equatable { let number: Int let square: Int let cube: Int class func convertFromIntegerLiteral(value: Int) -> CustomRawType { return CustomRawType(number: value) } init(number: Int) { self.number = number self.square = number * number self.cube = number * number * number }
func == (lhs: CustomRawType, rhs: CustomRawType) -> Bool { return lhs.number == rhs.number } }
![Page 27: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/27.jpg)
• Структура или final класс • Equatable протокол • Любой *LiteralConvertible протокол
enum Number2: CustomRawType { case One = 1 case Two = 2 case Three = 3 }
let three = Number2.Three let rawThree = three.toRaw() rawThree.cube
![Page 28: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/28.jpg)
Generic
![Page 29: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/29.jpg)
Generiс
• Одна из самых интересных особенностей Swift
• Повышает гибкость и переиспользуемость кода
• Swift Standard Library во многом написана с использованием Generic типов
![Page 30: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/30.jpg)
Generic функции
![Page 31: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/31.jpg)
Generic функции
func genericSwap<T>(inout a: T, inout b: T) {
![Page 32: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/32.jpg)
Generic функции
func genericSwap<T>(inout a: T, inout b: T) { let temp = b
![Page 33: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/33.jpg)
Generic функции
func genericSwap<T>(inout a: T, inout b: T) { let temp = b b = a
![Page 34: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/34.jpg)
Generic функции
func genericSwap<T>(inout a: T, inout b: T) { let temp = b b = a a = temp
![Page 35: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/35.jpg)
Generic функции
func genericSwap<T>(inout a: T, inout b: T) { let temp = b b = a a = temp}
![Page 36: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/36.jpg)
Generic функции
func genericSwap<T>(inout a: T, inout b: T) { let temp = b b = a a = temp}
![Page 37: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/37.jpg)
Generic функции
func genericSwap<T>(inout a: T, inout b: T) { let temp = b b = a a = temp}
var a_s = "a"
![Page 38: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/38.jpg)
Generic функции
func genericSwap<T>(inout a: T, inout b: T) { let temp = b b = a a = temp}
var a_s = "a"var b_s = "a"
![Page 39: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/39.jpg)
Generic функции
func genericSwap<T>(inout a: T, inout b: T) { let temp = b b = a a = temp}
var a_s = "a"var b_s = "a"var a_i = 1
![Page 40: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/40.jpg)
Generic функции
func genericSwap<T>(inout a: T, inout b: T) { let temp = b b = a a = temp}
var a_s = "a"var b_s = "a"var a_i = 1var b_i = 2
![Page 41: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/41.jpg)
Generic функции
func genericSwap<T>(inout a: T, inout b: T) { let temp = b b = a a = temp}
var a_s = "a"var b_s = "a"var a_i = 1var b_i = 2genericSwap(&a_s, &b_s)
![Page 42: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/42.jpg)
Generic функции
func genericSwap<T>(inout a: T, inout b: T) { let temp = b b = a a = temp}
var a_s = "a"var b_s = "a"var a_i = 1var b_i = 2genericSwap(&a_s, &b_s)genericSwap(&a_i, &b_i)
![Page 43: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/43.jpg)
Generic типы
![Page 44: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/44.jpg)
Generic типыclass GenericStack<T> { var elements = [T]() func push(object: T) { elements.append(object) } func pop() { elements.removeLast() } func peek() -> T? { return elements.last } func isEmpty() -> Bool { return elements.isEmpty } }
![Page 45: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/45.jpg)
Generic типыclass GenericStack<T> { var elements = [T]() func push(object: T) { elements.append(object) } func pop() { elements.removeLast() } func peek() -> T? { return elements.last } func isEmpty() -> Bool { return elements.isEmpty } }
let intStack = GenericStack<Int>() intStack.push(12) intStack.push(123) intStack.pop()
let stringStack = GenericStack<String>() stringStack.push("a") stringStack.push("ba") stringStack.pop()
![Page 46: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/46.jpg)
Ограничения на типы
![Page 47: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/47.jpg)
Ограничения на типыclass MyClass { }
![Page 48: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/48.jpg)
Ограничения на типыclass MyClass { }protocol MyProtocol { }
![Page 49: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/49.jpg)
Ограничения на типыclass MyClass { }protocol MyProtocol { }class MyClassWithProtocol: MyProtocol { }
![Page 50: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/50.jpg)
Ограничения на типыclass MyClass { }protocol MyProtocol { }class MyClassWithProtocol: MyProtocol { }class MyClass2: MyClass { }
![Page 51: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/51.jpg)
Ограничения на типыclass MyClass { }protocol MyProtocol { }class MyClassWithProtocol: MyProtocol { }class MyClass2: MyClass { }class MyClass3: MyClass, MyProtocol { }
![Page 52: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/52.jpg)
Ограничения на типыclass MyClass { }protocol MyProtocol { }class MyClassWithProtocol: MyProtocol { }class MyClass2: MyClass { }class MyClass3: MyClass, MyProtocol { }
![Page 53: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/53.jpg)
Ограничения на типыclass MyClass { }protocol MyProtocol { }class MyClassWithProtocol: MyProtocol { }class MyClass2: MyClass { }class MyClass3: MyClass, MyProtocol { }
class Example<T: MyClass, U: MyProtocol> { }
![Page 54: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/54.jpg)
Ограничения на типыclass MyClass { }protocol MyProtocol { }class MyClassWithProtocol: MyProtocol { }class MyClass2: MyClass { }class MyClass3: MyClass, MyProtocol { }
class Example<T: MyClass, U: MyProtocol> { }
![Page 55: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/55.jpg)
Ограничения на типыclass MyClass { }protocol MyProtocol { }class MyClassWithProtocol: MyProtocol { }class MyClass2: MyClass { }class MyClass3: MyClass, MyProtocol { }
class Example<T: MyClass, U: MyProtocol> { }
// compile error
![Page 56: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/56.jpg)
Ограничения на типыclass MyClass { }protocol MyProtocol { }class MyClassWithProtocol: MyProtocol { }class MyClass2: MyClass { }class MyClass3: MyClass, MyProtocol { }
class Example<T: MyClass, U: MyProtocol> { }
// compile error// let example = Example<Int, Double>()
![Page 57: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/57.jpg)
Ограничения на типыclass MyClass { }protocol MyProtocol { }class MyClassWithProtocol: MyProtocol { }class MyClass2: MyClass { }class MyClass3: MyClass, MyProtocol { }
class Example<T: MyClass, U: MyProtocol> { }
// compile error// let example = Example<Int, Double>()let example2 = Example<MyClass, MyClassWithProtocol>()
![Page 58: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/58.jpg)
Ограничения на типыclass MyClass { }protocol MyProtocol { }class MyClassWithProtocol: MyProtocol { }class MyClass2: MyClass { }class MyClass3: MyClass, MyProtocol { }
class Example<T: MyClass, U: MyProtocol> { }
// compile error// let example = Example<Int, Double>()let example2 = Example<MyClass, MyClassWithProtocol>()let example3 = Example<MyClass2, MyClassWithProtocol>()
![Page 59: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/59.jpg)
Ограничения на типыclass MyClass { }protocol MyProtocol { }class MyClassWithProtocol: MyProtocol { }class MyClass2: MyClass { }class MyClass3: MyClass, MyProtocol { }
class Example<T: MyClass, U: MyProtocol> { }
// compile error// let example = Example<Int, Double>()let example2 = Example<MyClass, MyClassWithProtocol>()let example3 = Example<MyClass2, MyClassWithProtocol>()let example4 = Example<MyClass3, MyClass3>() // OK
![Page 60: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/60.jpg)
Ассоциированные типы
protocol Stack { typealias ObjectType func push(object: ObjectType) func pop() func peek() -> ObjectType? }
ObjectType будет объявлен позже: в классе, который реализует протокол
![Page 61: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/61.jpg)
// Stack protocol автоматически возьмёт T // в качестве типа для typealias ObjectType class AnotherGenericStack<T>: Stack { var elements = [T]() func isEmpty() -> Bool { return elements.isEmpty } func push(object: T) { elements.append(object) } func pop() { elements.removeLast() } func peek() -> T? { return elements.last } }
![Page 62: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/62.jpg)
class IntStack: Stack { var elements = [Int]() func isEmpty() -> Bool { return elements.isEmpty } // Для не-generic типов нужно // явно объявить тип для typealias ObjectType typealias ObjectType = Int func push(object: ObjectType) { elements.append(object) } func pop() { elements.removeLast() } func peek() -> ObjectType? { return elements.last } }
![Page 63: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/63.jpg)
Протоколы
![Page 65: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/65.jpg)
Протоколы
Протокол - это шаблон методов и свойств, которыми будет обладать определенный класс, структура или перечисление, если решит его реализовать
![Page 66: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/66.jpg)
Зачем нужны протоколы
![Page 67: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/67.jpg)
Зачем нужны протоколы
1. Безопасность Протоколы гарантируют проверку на реализацию всех необходимых методов и свойств
![Page 68: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/68.jpg)
Зачем нужны протоколы
1. Безопасность Протоколы гарантируют проверку на реализацию всех необходимых методов и свойств
2. Упрощенное использование Протоколы позволяют разработчику понять, какими свойствами обладает класс, структура или перечисление, не зная конкретный тип
![Page 69: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/69.jpg)
protocol Vehicle {
var wheels: Int { get set } var isRequiresFuel: Bool { get } func start() -> String }
![Page 70: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/70.jpg)
class Car: Vehicle { var wheels: Int = 4 let isRequiresFuel: Bool = true func start() -> String { return "Сar starts its journey" } }
var myCar = Car() myCar.wheels = 6 myCar.wheels // 6 myCar.isRequiresFuel // true myCar.start() // "Сar starts its journey"
![Page 71: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/71.jpg)
class Bike: Vehicle { var wheels: Int = 2 var isRequiresFuel: Bool init(isWithFuel: Bool) { self.isRequiresFuel = isWithFuel } func start() -> String { return "Bike starts its journey" } }
var myTransport: Vehicle
myTransport = Bike(isWithFuel: false) myTransport.wheels // 2 myTransport.isRequiresFuel // false myTransport.start() // "Bike starts its journey"
myTransport = Car() myTransport.wheels // 4
![Page 72: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/72.jpg)
protocol Togglable { mutating func toggle() var state: String { get } }
![Page 73: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/73.jpg)
enum OnOffSwitch: Togglable { case Off, On mutating func toggle() { switch self { case Off: self = On case On: self = Off } } var state: String { get { switch self { case Off: return "Off" case On: return "On" } } } }
![Page 74: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/74.jpg)
var switcher: Togglable = OnOffSwitch.On switcher.state // "On" switcher.toggle() switcher.state // “Off"
func getLamp() -> Togglable
var currentLamp: Togglable = getLamp() currentLamp.toggle()
![Page 75: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/75.jpg)
Optionals
![Page 76: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/76.jpg)
Природа Optionals
Optional тип - это на самом деле enum, который может содержать либо .None либо .Some(T)
Optionals позволяют отследить момент отсутствия значения у переменной
![Page 77: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/77.jpg)
Опциональность в Obj-C
У NSObject (супер-класс) могло быть значение nil (NULL).
Для Int и прочих базовых типов использовались константы (к примеру NSNotFound), которые определяли какое-то значение (к примеру -1 или INT_MAX)
![Page 78: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/78.jpg)
![Page 79: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/79.jpg)
Обозначения
T? - опциональный тип optional type
T! - косвенно раскрывающийся опциональный тип implicitly unwrapped optional
v? - вызов цепочки от опционального типа optional chaining
v! - распаковка опционального типа unwrapping optional
![Page 80: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/80.jpg)
enum Optional<T> : Reflectable, NilLiteralConvertible { case None case Some(T) init() init(_ some: T)
/// Haskell's fmap, which was mis-named func map<U>(f: (T) -> U) -> U? func getMirror() -> MirrorType static func convertFromNilLiteral() -> T? }
var optionalValue = Optional<Int>(5) // {Some 5} optionalValue = nil // nil optionalValue = 10 // {Some 10} optionalValue = Optional<Int>.None // nil optionalValue = Optional.Some(15) // {Some 15} optionalValue = Optional.convertFromNilLiteral() // nil
![Page 81: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/81.jpg)
var optionalObject: AnyObject? = nil
var object: AnyObject = nil COMPILATION ERROR: Type 'AnyObject' does not conform to the protocol 'NilLiteralConvertible
![Page 82: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/82.jpg)
Использование и базовые операции
var optionalString: String? // nil optionalString = "Content"
// Unwrapping. error if optionalString == nil optionalString! optionalString? // Optional chaining optionalString?.hasPrefix("Con") optionalString.hasPrefix("") COMPILE ERROR: String? does not have a member named “hasPrefix”
if let string = optionalString { // Safe unwrap // Use string }
![Page 83: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/83.jpg)
Первый “?” позволяет вызвать метод если object != nil Второй “?” вызывает method(params) только если у объекта таковой реализован (respondsToSelector в obj-c) object?.method?(params)
var jsonContent: AnyObject? jsonContent?.objectForKey?("content")?.objectForKey?("info")?[5]
![Page 84: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/84.jpg)
Косвенно раскрывающийся опциональный тип
implicitly unwrapped optionalsvar unwrappedOptionalString: String! // nil unwrappedOptionalString = "Content" // "Content"
if let str = unwrappedOptionalString { str.hasPrefix("co") // false // Work with str }
unwrappedOptionalString.hasPrefix("Co") // true
unwrappedOptionalString = nil unwrappedOptionalString?.hasPrefix("Co") // nil unwrappedOptionalString.hasPrefix("Co") RUNTIME ERROR: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
![Page 85: Swift School #2](https://reader036.vdocuments.us/reader036/viewer/2022062514/557f0155d8b42ac46e8b48b4/html5/thumbnails/85.jpg)
Вопросы