SlideShare a Scribd company logo
1 of 86
Download to read offline
Swift Школа
Сергей Пронин
Empatika
План
• Перечисления
• Generic
• Протоколы
• Optionals
Перечисления
Перечисления
Enumerations
• Полноценный тип (наравне с классами)
• Обладает свойствами класса 

конструкторы, вычисляемые свойства,
динамические методы (у объектов)
• Поддерживает расширения (extensions -
категории) и протоколы (protocols)
enum Animal {
// значения
case Dog
case Cat
case Fish
case Robot
}
enum LazyAnimal {
// Одного 'case' достаточно
case Dog, Cat, Fish, Robot
}
По умолчанию значениям не присваиваются 

Int эквиваленты
Каждое значение имеет тип своего перечисления
let pet = Animal.Dog
switch pet {
case .Dog:
println("WOF-WOF")
case .Cat:
println("MEOW")
case .Fish:
println("???")
case .Robot:
println("Death to humans!")
}
“Ассоциированные” значения
• Каждый объект перечисления может
содержать объект другого типа в качестве
соответствия
• В таком случае их типы могут быть разными
• Позволяет “ассоциировать” любую
информацию
enum Barcode {
case UPCA(Int, Int, Int)
case PDF417(String)
}
var productBarcode = Barcode.UPCA(1, 2, 3)
productBarcode = .PDF417("ABCD")
Ассоциированные значения доступны

в switch-case конструкции
Ассоциированные значения доступны

в switch-case конструкции
switch productBarcode {
Ассоциированные значения доступны

в switch-case конструкции
switch productBarcode {
case .UPCA(let system, let ident, let check):
Ассоциированные значения доступны

в switch-case конструкции
switch productBarcode {
case .UPCA(let system, let ident, let check):
println("UPCA with value of (system), (ident), (check).")
Ассоциированные значения доступны

в switch-case конструкции
switch productBarcode {
case .UPCA(let system, let ident, let check):
println("UPCA with value of (system), (ident), (check).")
case .PDF417(let code):
Ассоциированные значения доступны

в 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).")
Ассоциированные значения доступны

в 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).")
}
Ассоциированные значения доступны

в 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).")
}
Ассоциированные значения доступны

в 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
Ассоциированные значения доступны

в 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
switch productBarcode {
Ассоциированные значения доступны

в 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
switch productBarcode {
case let .UPCA(system, ident, check):
Ассоциированные значения доступны

в 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
switch productBarcode {
case let .UPCA(system, ident, check):
println("UPCA with value of (system), (ident), (check).")
Ассоциированные значения доступны

в 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
switch productBarcode {
case let .UPCA(system, ident, check):
println("UPCA with value of (system), (ident), (check).")
case let .PDF417(code):
Ассоциированные значения доступны

в 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
switch 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).")
Ассоциированные значения доступны

в 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
switch 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).")
}
“Замещающие” значения
• Каждый объект перечисления может быть
сопоставлен с объектом другого типа
• “Замещающие” значения не меняются (в
отличие от “ассоциированных”
• Допустимые типы:

Character, String, Double, Float, Int*
// для 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()
*
// свой тип для перечислений
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
}
}
• Структура или 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
Generic
Generiс
• Одна из самых интересных особенностей Swift
• Повышает гибкость и переиспользуемость кода
• Swift Standard Library во многом написана с
использованием Generic типов
Generic функции
Generic функции
func genericSwap<T>(inout a: T, inout b: T) {
Generic функции
func genericSwap<T>(inout a: T, inout b: T) {
let temp = b
Generic функции
func genericSwap<T>(inout a: T, inout b: T) {
let temp = b
b = a
Generic функции
func genericSwap<T>(inout a: T, inout b: T) {
let temp = b
b = a
a = temp
Generic функции
func genericSwap<T>(inout a: T, inout b: T) {
let temp = b
b = a
a = temp
}
Generic функции
func genericSwap<T>(inout a: T, inout b: T) {
let temp = b
b = a
a = temp
}
Generic функции
func genericSwap<T>(inout a: T, inout b: T) {
let temp = b
b = a
a = temp
}
var a_s = "a"
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"
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
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
var b_i = 2
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
var b_i = 2
genericSwap(&a_s, &b_s)
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
var b_i = 2
genericSwap(&a_s, &b_s)
genericSwap(&a_i, &b_i)
Generic типы
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
}
}
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()
Ограничения на типы
Ограничения на типы
class MyClass { }
Ограничения на типы
class MyClass { }
protocol MyProtocol { }
Ограничения на типы
class MyClass { }
protocol MyProtocol { }
class MyClassWithProtocol: MyProtocol { }
Ограничения на типы
class MyClass { }
protocol MyProtocol { }
class MyClassWithProtocol: MyProtocol { }
class MyClass2: MyClass { }
Ограничения на типы
class MyClass { }
protocol MyProtocol { }
class MyClassWithProtocol: MyProtocol { }
class MyClass2: MyClass { }
class MyClass3: MyClass, MyProtocol { }
Ограничения на типы
class MyClass { }
protocol MyProtocol { }
class MyClassWithProtocol: MyProtocol { }
class MyClass2: MyClass { }
class MyClass3: MyClass, MyProtocol { }
Ограничения на типы
class MyClass { }
protocol MyProtocol { }
class MyClassWithProtocol: MyProtocol { }
class MyClass2: MyClass { }
class MyClass3: MyClass, MyProtocol { }
class Example<T: MyClass, U: MyProtocol> { }
Ограничения на типы
class MyClass { }
protocol MyProtocol { }
class MyClassWithProtocol: MyProtocol { }
class MyClass2: MyClass { }
class MyClass3: MyClass, MyProtocol { }
class Example<T: MyClass, U: MyProtocol> { }
Ограничения на типы
class MyClass { }
protocol MyProtocol { }
class MyClassWithProtocol: MyProtocol { }
class MyClass2: MyClass { }
class MyClass3: MyClass, MyProtocol { }
class Example<T: MyClass, U: MyProtocol> { }
// compile error
Ограничения на типы
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>()
Ограничения на типы
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>()
Ограничения на типы
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>()
Ограничения на типы
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
Ассоциированные типы
protocol Stack {
typealias ObjectType
func push(object: ObjectType)
func pop()
func peek() -> ObjectType?
}
ObjectType будет объявлен позже: 

в классе, который реализует протокол
// 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
}
}
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
}
}
Протоколы
Александр Зимин
iOS developer
UX designer
azimin@me.com
Протоколы
Протокол - это шаблон методов и свойств,
которыми будет обладать определенный класс,
структура или перечисление, если решит его
реализовать
Зачем нужны протоколы
Зачем нужны протоколы
1. Безопасность 

Протоколы гарантируют проверку на реализацию
всех необходимых методов и свойств
Зачем нужны протоколы
1. Безопасность 

Протоколы гарантируют проверку на реализацию
всех необходимых методов и свойств
2. Упрощенное использование 

Протоколы позволяют разработчику понять, какими
свойствами обладает класс, структура или
перечисление, не зная конкретный тип
protocol Vehicle {
var wheels: Int { get set }
var isRequiresFuel: Bool { get }
func start() -> String
}
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"
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
protocol Togglable {
mutating func toggle()
var state: String { get }
}
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"
}
}
}
}
var switcher: Togglable = OnOffSwitch.On
switcher.state // "On"
switcher.toggle()
switcher.state // “Off"
func getLamp() -> Togglable
var currentLamp: Togglable = getLamp()
currentLamp.toggle()
Optionals
Природа Optionals
Optional тип - это на самом деле enum, 

который может содержать либо .None либо .Some(T)
Optionals позволяют отследить момент отсутствия
значения у переменной
Опциональность в Obj-C
У NSObject (супер-класс) могло быть значение nil
(NULL).
Для Int и прочих базовых типов использовались
константы (к примеру NSNotFound), которые
определяли какое-то значение (к примеру -1 или
INT_MAX)
Обозначения
T? - опциональный тип 

optional type

T! - косвенно раскрывающийся опциональный тип 

implicitly unwrapped optional

v? - вызов цепочки от опционального типа 

optional chaining

v! - распаковка опционального типа 

unwrapping optional
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
var optionalObject: AnyObject? = nil

var object: AnyObject = nil 

COMPILATION ERROR: Type 'AnyObject' does
not conform to the protocol
'NilLiteralConvertible
Использование и 

базовые операции
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
}
Первый “?” позволяет вызвать метод если object != nil
Второй “?” вызывает method(params) только если у объекта
таковой реализован (respondsToSelector в obj-c)
object?.method?(params)
var jsonContent: AnyObject?
jsonContent?.objectForKey?
("content")?.objectForKey?("info")?[5]
Косвенно раскрывающийся
опциональный тип

implicitly unwrapped optionals
var 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)
Вопросы
sergey@pronin.me

More Related Content

What's hot

JPoint 2015 - Javassist на службе Java-разработчика
JPoint 2015 - Javassist на службе Java-разработчикаJPoint 2015 - Javassist на службе Java-разработчика
JPoint 2015 - Javassist на службе Java-разработчикаAnton Arhipov
 
Мифы и легенды Java Stream API
Мифы и легенды Java Stream APIМифы и легенды Java Stream API
Мифы и легенды Java Stream APICEE-SEC(R)
 
9. java lecture library
9. java lecture library9. java lecture library
9. java lecture libraryMERA_school
 
Живые приложения с Rx
Живые приложения с RxЖивые приложения с Rx
Живые приложения с RxGoSharp
 
Java. Интерфейс Map - ассоциативные массивы.
Java. Интерфейс Map - ассоциативные массивы.Java. Интерфейс Map - ассоциативные массивы.
Java. Интерфейс Map - ассоциативные массивы.Unguryan Vitaliy
 
Java. Строки. Класс String.
Java. Строки. Класс String.Java. Строки. Класс String.
Java. Строки. Класс String.Unguryan Vitaliy
 
Курсы актерского мастерства
Курсы актерского мастерстваКурсы актерского мастерства
Курсы актерского мастерстваVasil Remeniuk
 
Как программировать на JavaScript и не выстрелить себе в ногу
Как программировать на JavaScript и не выстрелить себе в ногуКак программировать на JavaScript и не выстрелить себе в ногу
Как программировать на JavaScript и не выстрелить себе в ногуAndreyGeonya
 
8 встреча — Язык программирования Python (В. Ананьев)
8 встреча — Язык программирования Python (В. Ананьев)8 встреча — Язык программирования Python (В. Ананьев)
8 встреча — Язык программирования Python (В. Ананьев)Smolensk Computer Science Club
 
Mera Dev Fest - Swift vs. Obj-C
Mera Dev Fest - Swift vs. Obj-CMera Dev Fest - Swift vs. Obj-C
Mera Dev Fest - Swift vs. Obj-CSergey Pronin
 
05 - Java. Collections Framework и Generics
05 - Java. Collections Framework и Generics05 - Java. Collections Framework и Generics
05 - Java. Collections Framework и GenericsRoman Brovko
 
«QuickCheck в Python: проверка гипотез и поиск ошибок», Александр Шорин, Ramb...
«QuickCheck в Python: проверка гипотез и поиск ошибок», Александр Шорин, Ramb...«QuickCheck в Python: проверка гипотез и поиск ошибок», Александр Шорин, Ramb...
«QuickCheck в Python: проверка гипотез и поиск ошибок», Александр Шорин, Ramb...Mail.ru Group
 
Опыт применения активных объектов во встраиваемых системах. Архитектурные асп...
Опыт применения активных объектов во встраиваемых системах. Архитектурные асп...Опыт применения активных объектов во встраиваемых системах. Архитектурные асп...
Опыт применения активных объектов во встраиваемых системах. Архитектурные асп...Sigma Software
 
JPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profilerJPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profilerAnton Arhipov
 
Sergii Tsypanov "Performance 1001 Tips"
Sergii Tsypanov "Performance 1001 Tips"Sergii Tsypanov "Performance 1001 Tips"
Sergii Tsypanov "Performance 1001 Tips"LogeekNightUkraine
 

What's hot (20)

Kotlin with API tests
Kotlin with API testsKotlin with API tests
Kotlin with API tests
 
JPoint 2015 - Javassist на службе Java-разработчика
JPoint 2015 - Javassist на службе Java-разработчикаJPoint 2015 - Javassist на службе Java-разработчика
JPoint 2015 - Javassist на службе Java-разработчика
 
Мифы и легенды Java Stream API
Мифы и легенды Java Stream APIМифы и легенды Java Stream API
Мифы и легенды Java Stream API
 
PHP7 - что ожидать?
PHP7 - что ожидать?PHP7 - что ожидать?
PHP7 - что ожидать?
 
Thread
ThreadThread
Thread
 
Kotlin
KotlinKotlin
Kotlin
 
9. java lecture library
9. java lecture library9. java lecture library
9. java lecture library
 
Живые приложения с Rx
Живые приложения с RxЖивые приложения с Rx
Живые приложения с Rx
 
Java. Интерфейс Map - ассоциативные массивы.
Java. Интерфейс Map - ассоциативные массивы.Java. Интерфейс Map - ассоциативные массивы.
Java. Интерфейс Map - ассоциативные массивы.
 
Java. Строки. Класс String.
Java. Строки. Класс String.Java. Строки. Класс String.
Java. Строки. Класс String.
 
Курсы актерского мастерства
Курсы актерского мастерстваКурсы актерского мастерства
Курсы актерского мастерства
 
Как программировать на JavaScript и не выстрелить себе в ногу
Как программировать на JavaScript и не выстрелить себе в ногуКак программировать на JavaScript и не выстрелить себе в ногу
Как программировать на JavaScript и не выстрелить себе в ногу
 
8 встреча — Язык программирования Python (В. Ананьев)
8 встреча — Язык программирования Python (В. Ананьев)8 встреча — Язык программирования Python (В. Ананьев)
8 встреча — Язык программирования Python (В. Ананьев)
 
Charming python sc2-8
Charming python sc2-8Charming python sc2-8
Charming python sc2-8
 
Mera Dev Fest - Swift vs. Obj-C
Mera Dev Fest - Swift vs. Obj-CMera Dev Fest - Swift vs. Obj-C
Mera Dev Fest - Swift vs. Obj-C
 
05 - Java. Collections Framework и Generics
05 - Java. Collections Framework и Generics05 - Java. Collections Framework и Generics
05 - Java. Collections Framework и Generics
 
«QuickCheck в Python: проверка гипотез и поиск ошибок», Александр Шорин, Ramb...
«QuickCheck в Python: проверка гипотез и поиск ошибок», Александр Шорин, Ramb...«QuickCheck в Python: проверка гипотез и поиск ошибок», Александр Шорин, Ramb...
«QuickCheck в Python: проверка гипотез и поиск ошибок», Александр Шорин, Ramb...
 
Опыт применения активных объектов во встраиваемых системах. Архитектурные асп...
Опыт применения активных объектов во встраиваемых системах. Архитектурные асп...Опыт применения активных объектов во встраиваемых системах. Архитектурные асп...
Опыт применения активных объектов во встраиваемых системах. Архитектурные асп...
 
JPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profilerJPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profiler
 
Sergii Tsypanov "Performance 1001 Tips"
Sergii Tsypanov "Performance 1001 Tips"Sergii Tsypanov "Performance 1001 Tips"
Sergii Tsypanov "Performance 1001 Tips"
 

Similar to Swift School #2

Зачем нужна Scala?
Зачем нужна Scala?Зачем нужна Scala?
Зачем нужна Scala?Vasil Remeniuk
 
разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3Eugeniy Tyumentcev
 
разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3etyumentcev
 
основы Java переменные, циклы
основы Java   переменные, циклыосновы Java   переменные, циклы
основы Java переменные, циклыSergey Nemchinsky
 
Statis code analysis
Statis code analysisStatis code analysis
Statis code analysischashnikov
 
Интерпретирование языков с помощью Free-монад
Интерпретирование языков с помощью Free-монадИнтерпретирование языков с помощью Free-монад
Интерпретирование языков с помощью Free-монадZheka Kozlov
 
Scala and LiftWeb presentation (Russian)
Scala and LiftWeb presentation (Russian)Scala and LiftWeb presentation (Russian)
Scala and LiftWeb presentation (Russian)Dmitry Stropalov
 
Подробная презентация JavaScript 6 в 1
Подробная презентация JavaScript 6 в 1Подробная презентация JavaScript 6 в 1
Подробная презентация JavaScript 6 в 1Vasya Petrov
 
Web осень 2012 лекция 9
Web осень 2012 лекция 9Web осень 2012 лекция 9
Web осень 2012 лекция 9Technopark
 
Go Template Toolkit, Сергей Свистунов, Lazada
Go Template Toolkit, Сергей Свистунов, LazadaGo Template Toolkit, Сергей Свистунов, Lazada
Go Template Toolkit, Сергей Свистунов, LazadaMail.ru Group
 
Lambdas in java 8
Lambdas in java 8Lambdas in java 8
Lambdas in java 8chashnikov
 

Similar to Swift School #2 (20)

Java 8 puzzlers
Java 8 puzzlersJava 8 puzzlers
Java 8 puzzlers
 
Урок 7. Интерпретация и компиляция функциональных программ.
Урок 7. Интерпретация и компиляция функциональных программ.Урок 7. Интерпретация и компиляция функциональных программ.
Урок 7. Интерпретация и компиляция функциональных программ.
 
Зачем нужна Scala?
Зачем нужна Scala?Зачем нужна Scala?
Зачем нужна Scala?
 
разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3
 
разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3
 
основы Java переменные, циклы
основы Java   переменные, циклыосновы Java   переменные, циклы
основы Java переменные, циклы
 
Statis code analysis
Statis code analysisStatis code analysis
Statis code analysis
 
Интерпретирование языков с помощью Free-монад
Интерпретирование языков с помощью Free-монадИнтерпретирование языков с помощью Free-монад
Интерпретирование языков с помощью Free-монад
 
Scala and LiftWeb presentation (Russian)
Scala and LiftWeb presentation (Russian)Scala and LiftWeb presentation (Russian)
Scala and LiftWeb presentation (Russian)
 
C sharp deep dive
C sharp deep diveC sharp deep dive
C sharp deep dive
 
C# Deep Dive
C# Deep DiveC# Deep Dive
C# Deep Dive
 
Kotlin на практике
Kotlin на практикеKotlin на практике
Kotlin на практике
 
Fiche Révision POO
Fiche Révision POOFiche Révision POO
Fiche Révision POO
 
Javascript 1
Javascript 1Javascript 1
Javascript 1
 
Подробная презентация JavaScript 6 в 1
Подробная презентация JavaScript 6 в 1Подробная презентация JavaScript 6 в 1
Подробная презентация JavaScript 6 в 1
 
Web осень 2012 лекция 9
Web осень 2012 лекция 9Web осень 2012 лекция 9
Web осень 2012 лекция 9
 
Go Template Toolkit, Сергей Свистунов, Lazada
Go Template Toolkit, Сергей Свистунов, LazadaGo Template Toolkit, Сергей Свистунов, Lazada
Go Template Toolkit, Сергей Свистунов, Lazada
 
Scala
ScalaScala
Scala
 
Lambdas in java 8
Lambdas in java 8Lambdas in java 8
Lambdas in java 8
 
Scala for android
Scala for androidScala for android
Scala for android
 

More from Sergey Pronin

App in the Air Internship 2018
App in the Air Internship 2018App in the Air Internship 2018
App in the Air Internship 2018Sergey Pronin
 
Things you might have missed from CoreData
Things you might have missed from CoreDataThings you might have missed from CoreData
Things you might have missed from CoreDataSergey Pronin
 
Департамент Программной Инженерии
Департамент Программной ИнженерииДепартамент Программной Инженерии
Департамент Программной ИнженерииSergey Pronin
 
Empatika Design Hours
Empatika Design HoursEmpatika Design Hours
Empatika Design HoursSergey Pronin
 
Greenfield Feedback Squeek
Greenfield Feedback SqueekGreenfield Feedback Squeek
Greenfield Feedback SqueekSergey Pronin
 

More from Sergey Pronin (15)

App in the Air Internship 2018
App in the Air Internship 2018App in the Air Internship 2018
App in the Air Internship 2018
 
PTA Ancillaries
PTA AncillariesPTA Ancillaries
PTA Ancillaries
 
Things you might have missed from CoreData
Things you might have missed from CoreDataThings you might have missed from CoreData
Things you might have missed from CoreData
 
Департамент Программной Инженерии
Департамент Программной ИнженерииДепартамент Программной Инженерии
Департамент Программной Инженерии
 
Swift School #4
Swift School #4Swift School #4
Swift School #4
 
Swift School #3
Swift School #3Swift School #3
Swift School #3
 
Swift School #1
Swift School #1Swift School #1
Swift School #1
 
Empatika Design Hours
Empatika Design HoursEmpatika Design Hours
Empatika Design Hours
 
Greenfield Feedback Squeek
Greenfield Feedback SqueekGreenfield Feedback Squeek
Greenfield Feedback Squeek
 
Squeek School #8
Squeek School #8Squeek School #8
Squeek School #8
 
Squeek School #7
Squeek School #7Squeek School #7
Squeek School #7
 
Squeek school #6
Squeek school #6Squeek school #6
Squeek school #6
 
Squeek School #5
Squeek School #5Squeek School #5
Squeek School #5
 
Squeek school 4
Squeek school 4Squeek school 4
Squeek school 4
 
Squeek School #3
Squeek School #3Squeek School #3
Squeek School #3
 

Swift School #2

  • 2. План • Перечисления • Generic • Протоколы • Optionals
  • 4. Перечисления Enumerations • Полноценный тип (наравне с классами) • Обладает свойствами класса 
 конструкторы, вычисляемые свойства, динамические методы (у объектов) • Поддерживает расширения (extensions - категории) и протоколы (protocols)
  • 5. enum Animal { // значения case Dog case Cat case Fish case Robot } enum LazyAnimal { // Одного 'case' достаточно case Dog, Cat, Fish, Robot } По умолчанию значениям не присваиваются 
 Int эквиваленты Каждое значение имеет тип своего перечисления
  • 6. let pet = Animal.Dog switch pet { case .Dog: println("WOF-WOF") case .Cat: println("MEOW") case .Fish: println("???") case .Robot: println("Death to humans!") }
  • 7. “Ассоциированные” значения • Каждый объект перечисления может содержать объект другого типа в качестве соответствия • В таком случае их типы могут быть разными • Позволяет “ассоциировать” любую информацию
  • 8. enum Barcode { case UPCA(Int, Int, Int) case PDF417(String) } var productBarcode = Barcode.UPCA(1, 2, 3) productBarcode = .PDF417("ABCD")
  • 10. Ассоциированные значения доступны
 в switch-case конструкции switch productBarcode {
  • 11. Ассоциированные значения доступны
 в switch-case конструкции switch productBarcode { case .UPCA(let system, let ident, let check):
  • 12. Ассоциированные значения доступны
 в switch-case конструкции switch productBarcode { case .UPCA(let system, let ident, let check): println("UPCA with value of (system), (ident), (check).")
  • 13. Ассоциированные значения доступны
 в switch-case конструкции switch productBarcode { case .UPCA(let system, let ident, let check): println("UPCA with value of (system), (ident), (check).") case .PDF417(let code):
  • 14. Ассоциированные значения доступны
 в 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).")
  • 15. Ассоциированные значения доступны
 в 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).") }
  • 16. Ассоциированные значения доступны
 в 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).") }
  • 17. Ассоциированные значения доступны
 в 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
  • 18. Ассоциированные значения доступны
 в 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 switch productBarcode {
  • 19. Ассоциированные значения доступны
 в 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 switch productBarcode { case let .UPCA(system, ident, check):
  • 20. Ассоциированные значения доступны
 в 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 switch productBarcode { case let .UPCA(system, ident, check): println("UPCA with value of (system), (ident), (check).")
  • 21. Ассоциированные значения доступны
 в 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 switch productBarcode { case let .UPCA(system, ident, check): println("UPCA with value of (system), (ident), (check).") case let .PDF417(code):
  • 22. Ассоциированные значения доступны
 в 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 switch 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).")
  • 23. Ассоциированные значения доступны
 в 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 switch 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).") }
  • 24. “Замещающие” значения • Каждый объект перечисления может быть сопоставлен с объектом другого типа • “Замещающие” значения не меняются (в отличие от “ассоциированных” • Допустимые типы:
 Character, String, Double, Float, Int*
  • 25. // для 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()
  • 26. * // свой тип для перечислений 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 } }
  • 27. • Структура или 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
  • 29. Generiс • Одна из самых интересных особенностей Swift • Повышает гибкость и переиспользуемость кода • Swift Standard Library во многом написана с использованием Generic типов
  • 32. Generic функции func genericSwap<T>(inout a: T, inout b: T) { let temp = b
  • 33. Generic функции func genericSwap<T>(inout a: T, inout b: T) { let temp = b b = a
  • 34. Generic функции func genericSwap<T>(inout a: T, inout b: T) { let temp = b b = a a = temp
  • 35. Generic функции func genericSwap<T>(inout a: T, inout b: T) { let temp = b b = a a = temp }
  • 36. Generic функции func genericSwap<T>(inout a: T, inout b: T) { let temp = b b = a a = temp }
  • 37. Generic функции func genericSwap<T>(inout a: T, inout b: T) { let temp = b b = a a = temp } var a_s = "a"
  • 38. 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"
  • 39. 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
  • 40. 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 var b_i = 2
  • 41. 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 var b_i = 2 genericSwap(&a_s, &b_s)
  • 42. 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 var b_i = 2 genericSwap(&a_s, &b_s) genericSwap(&a_i, &b_i)
  • 44. 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 } }
  • 45. 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()
  • 48. Ограничения на типы class MyClass { } protocol MyProtocol { }
  • 49. Ограничения на типы class MyClass { } protocol MyProtocol { } class MyClassWithProtocol: MyProtocol { }
  • 50. Ограничения на типы class MyClass { } protocol MyProtocol { } class MyClassWithProtocol: MyProtocol { } class MyClass2: MyClass { }
  • 51. Ограничения на типы class MyClass { } protocol MyProtocol { } class MyClassWithProtocol: MyProtocol { } class MyClass2: MyClass { } class MyClass3: MyClass, MyProtocol { }
  • 52. Ограничения на типы class MyClass { } protocol MyProtocol { } class MyClassWithProtocol: MyProtocol { } class MyClass2: MyClass { } class MyClass3: MyClass, MyProtocol { }
  • 53. Ограничения на типы class MyClass { } protocol MyProtocol { } class MyClassWithProtocol: MyProtocol { } class MyClass2: MyClass { } class MyClass3: MyClass, MyProtocol { } class Example<T: MyClass, U: MyProtocol> { }
  • 54. Ограничения на типы class MyClass { } protocol MyProtocol { } class MyClassWithProtocol: MyProtocol { } class MyClass2: MyClass { } class MyClass3: MyClass, MyProtocol { } class Example<T: MyClass, U: MyProtocol> { }
  • 55. Ограничения на типы class MyClass { } protocol MyProtocol { } class MyClassWithProtocol: MyProtocol { } class MyClass2: MyClass { } class MyClass3: MyClass, MyProtocol { } class Example<T: MyClass, U: MyProtocol> { } // compile error
  • 56. Ограничения на типы 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>()
  • 57. Ограничения на типы 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>()
  • 58. Ограничения на типы 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>()
  • 59. Ограничения на типы 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
  • 60. Ассоциированные типы protocol Stack { typealias ObjectType func push(object: ObjectType) func pop() func peek() -> ObjectType? } ObjectType будет объявлен позже: 
 в классе, который реализует протокол
  • 61. // 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 } }
  • 62. 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 } }
  • 65. Протоколы Протокол - это шаблон методов и свойств, которыми будет обладать определенный класс, структура или перечисление, если решит его реализовать
  • 67. Зачем нужны протоколы 1. Безопасность 
 Протоколы гарантируют проверку на реализацию всех необходимых методов и свойств
  • 68. Зачем нужны протоколы 1. Безопасность 
 Протоколы гарантируют проверку на реализацию всех необходимых методов и свойств 2. Упрощенное использование 
 Протоколы позволяют разработчику понять, какими свойствами обладает класс, структура или перечисление, не зная конкретный тип
  • 69. protocol Vehicle { var wheels: Int { get set } var isRequiresFuel: Bool { get } func start() -> String }
  • 70. 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"
  • 71. 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
  • 72. protocol Togglable { mutating func toggle() var state: String { get } }
  • 73. 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" } } } }
  • 74. var switcher: Togglable = OnOffSwitch.On switcher.state // "On" switcher.toggle() switcher.state // “Off" func getLamp() -> Togglable var currentLamp: Togglable = getLamp() currentLamp.toggle()
  • 76. Природа Optionals Optional тип - это на самом деле enum, 
 который может содержать либо .None либо .Some(T) Optionals позволяют отследить момент отсутствия значения у переменной
  • 77. Опциональность в Obj-C У NSObject (супер-класс) могло быть значение nil (NULL). Для Int и прочих базовых типов использовались константы (к примеру NSNotFound), которые определяли какое-то значение (к примеру -1 или INT_MAX)
  • 78.
  • 79. Обозначения T? - опциональный тип 
 optional type T! - косвенно раскрывающийся опциональный тип 
 implicitly unwrapped optional v? - вызов цепочки от опционального типа 
 optional chaining v! - распаковка опционального типа 
 unwrapping optional
  • 80. 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
  • 81. var optionalObject: AnyObject? = nil
 var object: AnyObject = nil 
 COMPILATION ERROR: Type 'AnyObject' does not conform to the protocol 'NilLiteralConvertible
  • 82. Использование и 
 базовые операции 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 }
  • 83. Первый “?” позволяет вызвать метод если object != nil Второй “?” вызывает method(params) только если у объекта таковой реализован (respondsToSelector в obj-c) object?.method?(params) var jsonContent: AnyObject? jsonContent?.objectForKey? ("content")?.objectForKey?("info")?[5]
  • 84. Косвенно раскрывающийся опциональный тип
 implicitly unwrapped optionals var 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)