Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.
EZ-‐‑‒NET  熊⾕谷友宏  
http://ez-‐‑‒net.jp/
2015.07.25  
@  カジュアル  Swift  勉強会  #1
Swift  2.0  で変わったところ
Swift  カジュアルプログラミング
(前編)
熊谷友宏
EZ-NET http://ez-net.jp/
@es_kumagai
Xcode 5 徹底解説
IP Phone 音でダイヤル 音で再配達ゴッド
いつもの電卓
with 割勘ウォッチ
MOSA
̶ 勉強会開催 ̶
#yidev 横...
新言語 Swift 登場
2014.06.02 @ WWDC 2014
Swift 2.0 登場
2015.06.08 @ WWDC 2015
大幅な仕様変更
?
そこで
Swift 2.0 で変わったところを
ざっくり紹介してみる
制御構文
1/4
guard
▶ 以降、条件式を満たすことを保証
▶ 満たさなければスコープの終了を保証
▶ 早期 Exit
guard《予防線》
guard expression else {
// 条件を満たさない場合は

// ここでスコープを抜ける実装を書く
}
/...
早期 Exit を保証
guard
guard value != 0 else {
// ここでスコープを抜けるコードを書かないとエラー
}
'guard' body may not fall through, consider
using '...
変数が 0 以外であることを保証
guard
guard value2 != 0 else {
// 0 の場合は結果を 0 とみなす
return 0
}
// これ以降は 0 ではないこと前提で記載できる
return value1 / v...
変数が nil でないことを保証
guard
guard let value = optional else {
// nil の場合は結果を .Unknown とする
return .Unknown
}
// これ以降は value を使って...
複雑な条件を指定して保証
guard
guard let path = getPath()
where path.hasPrefix("/Volumes") else {
fatalError()
}
// 変数 path が "/Volume...
defer
▶ スコープを抜ける直前に実行する
▶ defer の内部で

直前までに宣言された変数が使える
defer《繰り延べ》
defer {
// スコープを抜ける寸前に実行したい処理を記載
}
スコープを抜ける直前に実行
defer
var handle:Handle = File.open(path)
// 最後に必ずリソースを閉じる
defer {
handle.close()
}
// スコープを抜けない限りはリソースを使える
...
複数の defer を実行
defer
defer {
print(1)
}
defer {
print(2)
}
▶ 最後にスタック順に実行

2 → 1
入れ子にして defer を実行
defer
defer {
defer {
print(1)
}
print(2)
}
▶ defer を抜ける直前で実行

2 → 1
複数呼び出しと入れ子の複合
defer
defer {
defer {
print(1)
}
print(2)
}
defer {
print(3)
}
▶ ルールどおりの順序

3 → 2 → 1
repeat-while
▶ ブロックを実行し、最後に条件判定
▶ 従前の do-while 構文
▶ 条件式は repeat ブロックの外の扱い
repeat-while《繰り返し》
repeat {
// 処理を書く

// この処理を実行後に条件判定
} whil...
実行後に条件判定
repeat-while
var count = 100
repeat {
// 先にブロックを実行
--count
} while count > 0 // ブロックを抜けて条件判定
スコープ内の変数は使えない
repeat-while
let value = 100
repeat {
// while 条件式はスコープの外
let condition = array.contains(value)
} while cond...
repeat-while の
使いどころが想像できない
上⼿手な
do-catch
▶ エラーハンドリング専用構文
▶ 投げられた ErrorType を捕捉
▶ ErrorType は列挙型または NSError
do-catch《エラーハンドリング》
do {
// エラーが発生する可能性のあるコードを記載

} catc...
エラーの発生と捕捉
do-catch
do {
// エラーが発生するポイントで try を明記
var handle = try File.open(path)
// エラーがなければスコープ内の処理を続行
} catch {
// エラー発...
Error Handling
2/4
Error Handling
エラーの定義方法
Error Handling
// 列挙型でエラーを定義
enum FileOperationError : ErrorType {
case FailedToOpen
case NotPermitted(String)
}
...
エラーの送出方法
Error Handling
// 列挙子を指定してエラー送信
throw FileOperationError.FailedToOpen
// NSError でエラーを送信
throw NSError(domain:
NS...
エラーを詳しく捕捉
Error Handling
do {
var handle = try File.open(path)
} catch FileOperationError.FailedToOpen {
// エラーの種類を明記して捕捉
...
値付きのエラーを捕捉
Error Handling
do {
var handle = try File.open(path)
} catch FileOperationError
.NotPermitted(let reason) {
// ...
エラーを大雑把に捕捉(詳細を変数で捕捉)
Error Handling
do {
var handle = try File.open(path)
} catch let error as FileOperationError {
// 列挙型...
エラーを大雑把に捕捉(詳細を破棄)
Error Handling
do {
var handle = try File.open(path)
} catch is FileOperationError {
// 列挙型全体で捕捉
} catch...
スコープ内で投げたエラーも捕捉可能
Error Handling
do {
// スコープ内で明示的に投げたエラーも捕捉可能
throw FileOperationError.FailedToOpen
} catch FileOperation...
NSError Handing
ErrorType は NSError にキャスト可能
NSError Handling
let error
= FileOperationError.FailedToOpen as NSError
▶ Error Domain は列挙型名
▶...
捕捉時に NSError に変換可能
NSError Handling
do {
var handle = try File.open(path)
} catch let error as NSError {
// NSError と一緒に扱え...
エラーの扱い
エラーが起こり得ないなら
エラーの扱い
do {
var handle = try! File.open(path)
} catch {
}
▶ エラーが起こり得ないなら try!
▶ do-catch が不要
▶ もしエラーが発生すると強制終了
呼び出し元にエラー処理を委ねる
エラーの扱い
// 引数リストの次に throws を記載
func execute() throws -> String {
// 捕捉しないエラーを呼び出し元へ throw する
var handle = t...
エラーの一部を呼び出し元に委ねる
エラーの扱い
func execute() throws -> String {
// エラーの一部を捕捉する
do {
var handle = try File.open(path)
}
catch Fil...
引数でエラーを発生するかを決める
エラーの扱い
// エラーが起こり得る関数を引数にとり

// 関数リストの後に rethrows を明記
func execute(f:() throws -> Void) rethrows
-> Strin...
引数でエラーを発生するかを決める
エラーの扱い
// エラーが起こり得る関数を引数にとり

// 関数リストの後に rethrows を明記
func execute(f:() throws -> Void) rethrows
-> Strin...
引数でエラーが発生するかが決まる
エラーの扱い
// エラーが発生するかもしれない関数を渡せる
// その場合は try が必要になる
try execute { () throws -> Void in
}
// エラーが発生しない関数も渡せ...
詳細な条件指定
3/4
Pattern Matching
列挙子を扱う(前提)
Pattern Matching
// このような場面を想定したとき
enum Platform {
case IOS(Double)
case OSX(Double)
}
let platform = Platform....
if 文で列挙子を判定
Pattern Matching
// 列挙子から直接、添えた値を抽出可能
if case .OSX = platform {
}
列挙子に添えた値を抽出
Pattern Matching
// 列挙子から直接、添えた値を抽出可能
if case let .OSX(version) = platform {
print(version)
}
オプショナルから値を抽出
Pattern Matching
// 意味的には Optional Binding と同等
if case let value? = optional {
print(value)
}
複数のオプショナルから値を抽出
Pattern Matching
// タプルを使ってまとめて変換が可能
if case let (a?, b?, c?)
= (optionalA, optionalB, optionalC) {
// すべて...
値が範囲に含まれるか判定
Pattern Matching
// たとえば数値
if case 0 ..< 100 = value {
print("contains")
}
// たとえば文字列
if case "A" ..< "G" = s...
条件指定
if 文に where で条件を添える
条件指定
// Swift 1.2 でも使えた記載方法
if let string = optionalString
where string.hasSuffix(".png") {
}
パターンマッチとの併用も可能
条件指定
// 列挙子から値を抽出して条件判定
if case let .OSX(version) = platform
where version > 10.10 {
}
// 複数のオプショナルを展開して条件判...
guard でも使える
条件指定
// 列挙子から値を抽出して条件判定
guard case let .OSX(version) = platform
where version > 10.10 else {
}
// 複数のオプショナルを展開...
for でも使える
条件指定
// nil 以外の要素で繰り返し
let optionals:[Int?]
for case let value? in optionals {
}
▶ ループの中で判定しなくて良い
▶ fratMap { $0...
for でも使える
条件指定
// nil 以外の繰り返しに条件まで付けられる
let optionals:[Int?]
for case let value? in optionals
where value > 0 {
}
▶ 該当した要素...
Extension
4/4
Protocol Extension
▶ プロトコルに既定の実装を添える仕組み
▶ 型エイリアスで実装条件を絞れる
Protocol Extension
extension Protocol {
func doSomething() {
// ここに実装を記載できる
}
}
既定の実装
Protocol Extension
extension CollectionType {
var count:Index.Distance {
return distance(
self.startIndex, self.endI...
条件付きで拡張
Protocol Extension
extension CollectionType
where Generator.Element : IntegerType {
var sum:Generator.Element {
re...
複数の条件で縛る
Protocol Extension
extension CollectionType where
Index : Streamable,
Generator.Element : IntegerType {
func prin...
同じ型であることを明記
Protocol Extension
extension CollectionType where
Generator.Element : IntegerType,
Index.Distance == Generator...
自分自身を条件で縛る
Protocol Extension
extension CollectionType where
Self : Equatable,
Self : NillLiteralConvertible {
var isNull:...
明示的に型で縛る
Protocol Extension
extension CollectionType where
Generator.Element == String {
var lastPathComponents:String {
r...
既定の実装は上書き可能
Protocol Extension
extension MyProtocol {
var isValid:Bool {
return false
}
}
struct MyStruct : MyProtocol {
v...
継承して上書き可能
Protocol Extension
protocol MyProtoA {
}
protocol MyProtoB : MyProtoA {
}
extension MyProtoA {
func action() -> ...
親を呼ぶ、みたいなことはできない
Protocol Extension
extension MyProtoA {
func action() -> Int {
}
}
extension MyProtoB {
func action() -> ...
キャストで呼び出し先を明記可能
Protocol Extension
extension MyProtoA {
func action() -> Int {
}
}
extension MyProtoB {
func action() -> I...
Type Extension
▶ 従来からある型の拡張方法
▶ Swift 2 から

ジェネリックパラメータで条件を絞れる
Type Extension
extension Array where Element : IntegerType {
func doSometh...
条件をプロトコルで縛る
Type Extension
extension Optional where T : SignedNumberType {
var negative:Optional {
return self.map { -$0 }...
型では縛れない
Type Extension
extension Optional where T == String {
}
Same-type requirement makes
generic parameter 'T' non-gene...
型の拡張は 既定の実装 ではない
Type Extension
extension MyStruct {
var isValid:Bool {
return false
}
}
struct MyStruct {
var isValid:Boo...
後編
Coming Soon ?
Swift 2.0 で変わったところ(前編)
▶ 制御構文
▶ Error Handling
▶ 詳細な条件指定
▶ Extension
Nächste SlideShare
Wird geladen in …5
×

Swift 2.0 で変わったところ「前編」 #cswift

2015.07.25 に開催した『カジュアル Swift 勉強会』で、Swift 2.0 での変更点をざっくりと紹介してみました。気づいた全部を紹介するつもりでいたんですけど、思いのほか量が多くてひとまずは「前編」という形で、とりわけ目立つ変更点を取り上げてみます。

  • Als Erste(r) kommentieren

Swift 2.0 で変わったところ「前編」 #cswift

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

×