Swift2.0で追加された新機能 3選

こんにちは、Swiftエンジニアの杉本です。

先週、Swift2.0が発表されました。
そこで今回の投稿では、Swift2.0の新機能のなかで私が注目している3機能をご紹介します。

  • do-catch・try・defer
  • guard
  • Protocol Extension

 

do-catch・try・defer

do-catchはエラー処理に関する構文で、他の言語でのtry-catch構文にあたります。
基本的な使い方は下の通りです。

enum MyError: ErrorType {
    case Error1
    case Error2
}

do {
    throw MyError.Error1 // throwで例外を発生させる
} catch MyError.Error1 {
    print("Error1")
} catch let error {
    print(error)
}

例外が発生しうるメソッドにはthrowsを付ける必要があります。
呼び出し元ではdo-catchtryが必要です。

func method() throws -> String? {
    let value: String? = nil
    if value == nil { throw MyError.Error1 }
    return value
}

do {
    let str = try method()
    print(str)
} catch {
    print("error")
}

try!を使えばdo-catchは不要です。
しかし、method内で例外が投げられた時はアプリが落ちるので気をつけて使う必要があります。

try! method()

必ず通ってほしい処理はdeferを使って記述します。
deferで定義された処理はブロックの最後に必ず実行されます。

deferは例外の前に書かないと呼ばれないのでそこだけ注意する必要があります。

// 1 → 2 → 3 という順番で出力される
do {
    defer {
        // 例外が発生してもしなくてもここを通る
        print("2")
    }
    print("1")
    try method()
    defer {
        // これは呼ばれない
        print("4")
    }
} catch {
    print("3")
}

 

guard

guardは早期リターンに関する構文です。
今まであったif let a = b {}構文に近いものです。
基本的な使い方は下の通りです。

func method() {
    var dic = Dictionary<String,Int>()
    dic["key"] = nil

    guard let value = dic["key"] else {
        print("nil") // valueがnilならここを通る
        return // returnは必須
    }
    print(value)
}

method()

これは下のような書き方と同義です。

func method() {
    var dic = Dictionary<String,Int>()
    dic["key"] = 1

    if let value = dic["key"] {
        print(value)
    } else {
        print("nil")
    }
}

method()

if letと同様にwhere節も使えます。
こちらは条件がfalseの時に括弧内の処理が走ります。
複雑な条件を入れると混乱しそうですね。

func method() {
    var dic = Dictionary<String,Int>()
    dic["key"] = 1

    guard let value = dic["key"] where value != 1 else {
        print("value == 1")
        return
    }
    print(value)
}

method()

 

Protocol Extension

プロトコルにメソッドの実装を書く事ができる機能です。
下のようにextensionを使ってprotocolにメソッドを追加できます。

protocol MyProtocol {
    func method1()
}
extension MyProtocol {
    func method2() { print(2) }
}

class MyClass: MyProtocol {
    func method1() { print(1) }
}

MyClass().method1() // → 1
MyClass().method2() // → 2

protocolでのメソッド定義やextensionでのメソッド宣言はできません。

protocol MyProtocol {
    func method1() { print("") } // これはエラーになる
}
extension MyProtocol {
    var value: Int? // これもエラー、extensionでインスタンス変数は追加できない
    func method2() // これもエラー
}

extensionで追加したメソッドを上書きする事ができます。

protocol MyProtocol {}
extension MyProtocol {
    func method() { print("MyProtocol") } // これは呼ばれない
}
class MyClass: MyProtocol {
    func method() { print("MyClass") } // こっちが呼ばれる
}

MyClass().method() // → MyClass

 

参考

本エントリーは個人ブログで書いた下記記事を一部加筆修正したものです

上記以外のSwift2.0での変更点はこちらから確認できます。
ぜひチェックしてみて下さい。
 
 

最後に

マネーフォワードでは、新しい技術も積極的に取り入れていくエンジニアを募集しています。
ご応募お待ちしております!

【採用サイト】
『マネーフォワード採用サイト』 https://recruit.moneyforward.com/
『Wantedly』 https://www.wantedly.com/companies/moneyforward

【公開カレンダー】
マネーフォワード公開カレンダー

【プロダクト一覧】
家計簿アプリ・クラウド家計簿ソフト『マネーフォワード』 https://moneyforward.com/
家計簿アプリ・クラウド家計簿ソフト『マネーフォワード』 iPhone,iPad
家計簿アプリ・クラウド家計簿ソフト『マネーフォワード』 Android
クラウド型会計ソフト『MFクラウド会計』 https://biz.moneyforward.com/
クラウド型請求書管理ソフト『MFクラウド請求書』 https://invoice.moneyforward.com/
クラウド型給与計算ソフト『MFクラウド給与』 https://payroll.moneyforward.com/

Pocket