swift 2.0 で変わったところ「前編」 #cswift
TRANSCRIPT
![Page 1: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/1.jpg)
EZ-‐‑‒NET 熊⾕谷友宏 http://ez-‐‑‒net.jp/
2015.07.25 @ カジュアル Swift 勉強会 #1
Swift 2.0 で変わったところSwift カジュアルプログラミング
(前編)
![Page 2: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/2.jpg)
熊谷友宏EZ-NET http://ez-net.jp/ @es_kumagai
Xcode 5 徹底解説
IP Phone 音でダイヤル 音で再配達ゴッドいつもの電卓 with 割勘ウォッチ
MOSA
勉強会開催 #yidev 横浜 iPhone 開発者勉強会カジュアル Swift 勉強会 @ 青葉台
![Page 3: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/3.jpg)
新言語 Swift 登場 2014.06.02 @ WWDC 2014
Swift 2.0 登場 2015.06.08 @ WWDC 2015
![Page 4: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/4.jpg)
大幅な仕様変更
?
![Page 5: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/5.jpg)
そこで
![Page 6: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/6.jpg)
Swift 2.0 で変わったところを ざっくり紹介してみる
![Page 7: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/7.jpg)
制御構文1/4
![Page 8: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/8.jpg)
guard
![Page 9: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/9.jpg)
▶ 以降、条件式を満たすことを保証 ▶ 満たさなければスコープの終了を保証 ▶ 早期 Exit
guard《予防線》
guard expression else {
// 条件を満たさない場合は// ここでスコープを抜ける実装を書く
}
// これ以降は条件を満たしていることを保証
![Page 10: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/10.jpg)
早期 Exit を保証guard
guard value != 0 else {
// ここでスコープを抜けるコードを書かないとエラー
} 'guard' body may not fall through, consider using 'return' or 'break' to exit the scope
▶ return ▶ break ▶ continue ▶ fatalError
![Page 11: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/11.jpg)
変数が 0 以外であることを保証guard
guard value2 != 0 else {
// 0 の場合は結果を 0 とみなす return 0
}
// これ以降は 0 ではないこと前提で記載できる return value1 / value2
![Page 12: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/12.jpg)
変数が nil でないことを保証guard
guard let value = optional else {
// nil の場合は結果を .Unknown とする return .Unknown
}
// これ以降は value を使ってコーディングできる let data = calculate(value)
![Page 13: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/13.jpg)
複雑な条件を指定して保証guard
guard let path = getPath() where path.hasPrefix("/Volumes") else {
fatalError() }
// 変数 path が "/Volumes" で始まることを保証
![Page 14: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/14.jpg)
defer
![Page 15: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/15.jpg)
▶ スコープを抜ける直前に実行する ▶ defer の内部で直前までに宣言された変数が使える
defer《繰り延べ》
defer {
// スコープを抜ける寸前に実行したい処理を記載
}
![Page 16: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/16.jpg)
スコープを抜ける直前に実行defer
var handle:Handle = File.open(path)
// 最後に必ずリソースを閉じる defer { handle.close() }
// スコープを抜けない限りはリソースを使える string.writeTo(&handle)
![Page 17: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/17.jpg)
複数の defer を実行defer
defer { print(1) } defer { print(2) }
▶ 最後にスタック順に実行2 → 1
![Page 18: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/18.jpg)
入れ子にして defer を実行defer
defer { defer { print(1) } print(2) }
▶ defer を抜ける直前で実行2 → 1
![Page 19: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/19.jpg)
複数呼び出しと入れ子の複合defer
defer { defer { print(1) } print(2) } defer { print(3) }
▶ ルールどおりの順序3 → 2 → 1
![Page 20: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/20.jpg)
repeat-while
![Page 21: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/21.jpg)
▶ ブロックを実行し、最後に条件判定 ▶ 従前の do-while 構文 ▶ 条件式は repeat ブロックの外の扱い
repeat-while《繰り返し》
repeat {
// 処理を書く// この処理を実行後に条件判定
} while expression
![Page 22: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/22.jpg)
実行後に条件判定repeat-while
var count = 100
repeat {
// 先にブロックを実行 --count
} while count > 0 // ブロックを抜けて条件判定
![Page 23: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/23.jpg)
スコープ内の変数は使えないrepeat-while
let value = 100
repeat {
// while 条件式はスコープの外 let condition = array.contains(value)
} while condition // repeat 内の変数は使えない
Use of unresolved identifier 'condition'
![Page 24: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/24.jpg)
repeat-while の 使いどころが想像できない
上⼿手な
![Page 25: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/25.jpg)
do-catch
![Page 26: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/26.jpg)
▶ エラーハンドリング専用構文 ▶ 投げられた ErrorType を捕捉 ▶ ErrorType は列挙型または NSError
do-catch《エラーハンドリング》
do {
// エラーが発生する可能性のあるコードを記載
} catch {
// ここでエラー処理を行う }
![Page 27: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/27.jpg)
エラーの発生と捕捉do-catch
do {
// エラーが発生するポイントで try を明記 var handle = try File.open(path)
// エラーがなければスコープ内の処理を続行
} catch { // エラー発生時のみ実行// ErrorType 型の error 変数を参照可能
print(error) }
![Page 28: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/28.jpg)
Error Handling2/4
![Page 29: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/29.jpg)
Error Handling
![Page 30: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/30.jpg)
エラーの定義方法Error Handling
// 列挙型でエラーを定義 enum FileOperationError : ErrorType {
case FailedToOpen case NotPermitted(String) }
▶ 列挙型を ErrorType に準拠 ▶ 列挙型がエラードメイン ▶ 列挙子で関連するエラーを定義する
![Page 31: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/31.jpg)
エラーの送出方法Error Handling
// 列挙子を指定してエラー送信 throw FileOperationError.FailedToOpen
// NSError でエラーを送信 throw NSError(domain: NSInvalidArgumentException, code: 0, userInfo: nil)
![Page 32: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/32.jpg)
エラーを詳しく捕捉Error Handling
do {
var handle = try File.open(path)
} catch FileOperationError.FailedToOpen {
// エラーの種類を明記して捕捉
} catch { // すべてのエラーの捕捉も必須
}
![Page 33: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/33.jpg)
値付きのエラーを捕捉Error Handling
do {
var handle = try File.open(path)
} catch FileOperationError .NotPermitted(let reason) {
// 列挙子に添えられた値を取り出して使える
} catch { // すべてのエラーの捕捉も必須
}
![Page 34: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/34.jpg)
エラーを大雑把に捕捉(詳細を変数で捕捉)Error Handling
do {
var handle = try File.open(path)
} catch let error as FileOperationError {
// 列挙型全体で捕捉
} catch { // すべてのエラーの捕捉も必須
}
![Page 35: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/35.jpg)
エラーを大雑把に捕捉(詳細を破棄)Error Handling
do {
var handle = try File.open(path)
} catch is FileOperationError {
// 列挙型全体で捕捉
} catch { // すべてのエラーの捕捉も必須
}
![Page 36: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/36.jpg)
スコープ内で投げたエラーも捕捉可能Error Handling
do {
// スコープ内で明示的に投げたエラーも捕捉可能 throw FileOperationError.FailedToOpen
} catch FileOperationError.FailedToOpen { // エラー処理が実行される
}
![Page 37: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/37.jpg)
NSError Handing
![Page 38: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/38.jpg)
ErrorType は NSError にキャスト可能NSError Handling
let error = FileOperationError.FailedToOpen as NSError
▶ Error Domain は列挙型名 ▶ Error Code は 0 ▶ Description は “The operation couldn’t be completed. (…)”
![Page 39: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/39.jpg)
捕捉時に NSError に変換可能NSError Handling
do {
var handle = try File.open(path)
} catch let error as NSError { // NSError と一緒に扱える
print(error.localizedDescription) }
![Page 40: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/40.jpg)
エラーの扱い
![Page 41: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/41.jpg)
エラーが起こり得ないならエラーの扱い
do {
var handle = try! File.open(path)
} catch {
}
▶ エラーが起こり得ないなら try! ▶ do-catch が不要 ▶ もしエラーが発生すると強制終了
![Page 42: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/42.jpg)
呼び出し元にエラー処理を委ねるエラーの扱い
// 引数リストの次に throws を記載 func execute() throws -> String {
// 捕捉しないエラーを呼び出し元へ throw する var handle = try File.open(path)
}
![Page 43: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/43.jpg)
エラーの一部を呼び出し元に委ねるエラーの扱い
func execute() throws -> String {
// エラーの一部を捕捉する do {
var handle = try File.open(path)
} catch FileOperationError.NotPermitted {
}
// 捕捉しなかったエラーは呼び出し元に委ねる }
![Page 44: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/44.jpg)
引数でエラーを発生するかを決めるエラーの扱い
// エラーが起こり得る関数を引数にとり// 関数リストの後に rethrows を明記 func execute(f:() throws -> Void) rethrows -> String { try f()
// 受け取った関数以外でエラーは発生できない }
![Page 45: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/45.jpg)
引数でエラーを発生するかを決めるエラーの扱い
// エラーが起こり得る関数を引数にとり// 関数リストの後に rethrows を明記 func execute(f:() throws -> Void) rethrows -> String { try f()
// 受け取った関数以外でエラーは発生できない throw FileOperationError.FailedToOpen
}
'rethrows' function may only throw by calling a parameter function
![Page 46: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/46.jpg)
引数でエラーが発生するかが決まるエラーの扱い
// エラーが発生するかもしれない関数を渡せる // その場合は try が必要になる try execute { () throws -> Void in
}
// エラーが発生しない関数も渡せる // その場合は try が不要(エラーが起こり得ない) execute { () -> Void in
}
rethrows 指定の関数に限り好きな方を渡せる
![Page 47: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/47.jpg)
詳細な条件指定3/4
![Page 48: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/48.jpg)
Pattern Matching
![Page 49: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/49.jpg)
列挙子を扱う(前提)Pattern Matching
// このような場面を想定したとき enum Platform { case IOS(Double) case OSX(Double) }
let platform = Platform.OSX(10.11)
![Page 50: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/50.jpg)
if 文で列挙子を判定Pattern Matching
// 列挙子から直接、添えた値を抽出可能 if case .OSX = platform { }
![Page 51: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/51.jpg)
列挙子に添えた値を抽出Pattern Matching
// 列挙子から直接、添えた値を抽出可能 if case let .OSX(version) = platform { print(version)
}
![Page 52: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/52.jpg)
オプショナルから値を抽出Pattern Matching
// 意味的には Optional Binding と同等 if case let value? = optional { print(value)
}
![Page 53: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/53.jpg)
複数のオプショナルから値を抽出Pattern Matching
// タプルを使ってまとめて変換が可能 if case let (a?, b?, c?) = (optionalA, optionalB, optionalC) {
// すべてが nil でない場合に限り処理される print("\(a), \(b), \(c)")
}
![Page 54: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/54.jpg)
値が範囲に含まれるか判定Pattern Matching
// たとえば数値 if case 0 ..< 100 = value {
print("contains")
}
// たとえば文字列 if case "A" ..< "G" = string {
print("contains")
}
![Page 55: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/55.jpg)
条件指定
![Page 56: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/56.jpg)
if 文に where で条件を添える条件指定
// Swift 1.2 でも使えた記載方法 if let string = optionalString where string.hasSuffix(".png") { }
![Page 57: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/57.jpg)
パターンマッチとの併用も可能条件指定
// 列挙子から値を抽出して条件判定 if case let .OSX(version) = platform where version > 10.10 { }
// 複数のオプショナルを展開して条件判定 if case let (a?, b?, c?) = (optionalA, optionalB, optionalC) where a + b == c { }
![Page 58: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/58.jpg)
guard でも使える条件指定
// 列挙子から値を抽出して条件判定 guard case let .OSX(version) = platform where version > 10.10 else { }
// 複数のオプショナルを展開して条件判定 guard case let (a?, b?, c?) = (optionalA, optionalB, optionalC) where a + b == c else { }
![Page 59: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/59.jpg)
for でも使える条件指定
// nil 以外の要素で繰り返し let optionals:[Int?]
for case let value? in optionals { }
▶ ループの中で判定しなくて良い ▶ fratMap { $0 } でループさせなくて良い
![Page 60: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/60.jpg)
for でも使える条件指定
// nil 以外の繰り返しに条件まで付けられる let optionals:[Int?]
for case let value? in optionals where value > 0 { }
▶ 該当した要素だけが繰り返しの対象に
![Page 61: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/61.jpg)
Extension4/4
![Page 62: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/62.jpg)
Protocol Extension
![Page 63: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/63.jpg)
▶ プロトコルに既定の実装を添える仕組み ▶ 型エイリアスで実装条件を絞れる
Protocol Extension
extension Protocol {
func doSomething() {
// ここに実装を記載できる }
}
![Page 64: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/64.jpg)
既定の実装Protocol Extension
extension CollectionType {
var count:Index.Distance { return distance( self.startIndex, self.endIndex) }
}
▶ プロトコルで決められた機能で実装を組み立てる
![Page 65: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/65.jpg)
条件付きで拡張Protocol Extension
extension CollectionType where Generator.Element : IntegerType {
var sum:Generator.Element { return self.reduce(0, combine: +) } }
▶ 型エイリアスをプロトコルで縛るとそれを想定した機能が使える
▶ 条件を満たす型だけに実装される
![Page 66: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/66.jpg)
複数の条件で縛るProtocol Extension
extension CollectionType where Index : Streamable, Generator.Element : IntegerType {
func printIndexOf<S:OutputStreamType> (element:Generator.Element, inout to stream:S) {
self.indexOf(element)?.writeTo(&stream) }
}
![Page 67: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/67.jpg)
同じ型であることを明記Protocol Extension
extension CollectionType where Generator.Element : IntegerType, Index.Distance == Generator.Element { var average:Generator.Element { return self.reduce(0) { $0 + $1 } / self.count }
var count:Index.Distance {
return distance( self.startIndex, self.endIndex) } }
![Page 68: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/68.jpg)
自分自身を条件で縛るProtocol Extension
extension CollectionType where Self : Equatable, Self : NillLiteralConvertible {
var isNull:Bool { return self == nil }
}
![Page 69: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/69.jpg)
明示的に型で縛るProtocol Extension
extension CollectionType where Generator.Element == String { var lastPathComponents:String { return self.map { $0.lastPathComponent } }
}
![Page 70: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/70.jpg)
既定の実装は上書き可能Protocol Extension
extension MyProtocol { var isValid:Bool { return false } }
struct MyStruct : MyProtocol {
var isValid:Bool {
return true }
}採⽤用
![Page 71: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/71.jpg)
継承して上書き可能Protocol Extension
protocol MyProtoA { }
protocol MyProtoB : MyProtoA { } extension MyProtoA { func action() -> Int { } } extension MyProtoB { func action() -> Int { } }
採⽤用
![Page 72: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/72.jpg)
親を呼ぶ、みたいなことはできないProtocol Extension
extension MyProtoA {
func action() -> Int { } }
extension MyProtoB { func action() -> Int {
return super.action() } }
'super' cannot be used outside of class members
![Page 73: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/73.jpg)
キャストで呼び出し先を明記可能Protocol Extension
extension MyProtoA {
func action() -> Int { } } extension MyProtoB { func action() -> Int {
return (self as MyProtoA).action() + 1 } }
![Page 74: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/74.jpg)
Type Extension
![Page 75: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/75.jpg)
▶ 従来からある型の拡張方法 ▶ Swift 2 からジェネリックパラメータで条件を絞れる
Type Extension
extension Array where Element : IntegerType {
func doSomething() {
} }
![Page 76: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/76.jpg)
条件をプロトコルで縛るType Extension
extension Optional where T : SignedNumberType { var negative:Optional { return self.map { -$0 } }
}
![Page 77: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/77.jpg)
型では縛れないType Extension
extension Optional where T == String { }
Same-type requirement makes generic parameter 'T' non-generic
![Page 78: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/78.jpg)
型の拡張は “既定の実装” ではないType Extension
extension MyStruct { var isValid:Bool { return false } }
struct MyStruct {
var isValid:Bool {
return true }
}
おさらい
Invalid redeclaration of 'isValid'
![Page 79: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/79.jpg)
後編Coming Soon ?
![Page 80: Swift 2.0 で変わったところ「前編」 #cswift](https://reader034.vdocuments.mx/reader034/viewer/2022050923/55caf886bb61eb9f2b8b46bb/html5/thumbnails/80.jpg)
Swift 2.0 で変わったところ(前編)
▶ 制御構文 ▶ Error Handling ▶ 詳細な条件指定 ▶ Extension