Swift 1.2のif let複数宣言と例外処理

  • 51
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

Swift1.2でif letでの複数の宣言が可能になった


func getA()->String?{
    return "A"
}

func getB()->String? {
    return "B"
}

func getC()->String?{
    return "C"
}


func test() -> (){
    // カンマ区切りで複数の変数のOptional判定 + 宣言が可能に
    if let a = getA(), b = getB(), c = getC(){
        print( a + b + c + "のすべてがnilではない ")
    }else{
        print( "a,b,cのうちどれかがnilの場合はfalse")
    }
}

if letの複数宣言では直前に解決した変数を使うことができる


func getA()->String?{
    return "A"
}

func getB(a:String)->String? {
    return a + "B"
}

func getC(b:String)->String?{
    return b + "C"
}


func test() -> (){
    if let a = getA(),
           b = getB(a), // ←直前に解決したaを引数として使用
           c = getC(b)  // ←直前に解決したbを引数として使用
    {
        print( a + b + c + "のすべてがnilではない ")
    }else{
        print( "a,b,cのうちどれかがnilの場合はfalse")
    }
}

つまりこれは
getA()
getB(a)
getC(c)
と逐次処理をして途中でnilが返されると処理を中断するような
簡易的な例外処理として機能する

例えばこれをSwift1.1の範疇で書こうとすると

if文のネストが深くなりめんどくさい

func test() -> (){
    if let a = getA(){
        if let b = getB(a) {
            if let c = getC(b) {
                print( a + b + c + "のすべてがnilではない ")
                return
            }
        }
    }
    print( "a,b,cのうちどれかがnilの場合はfalse")
}

if letの中で処理を書いてしまえ

いくつかユーティリティ的な関数を用意すると、if letの中で通常と処理と同じ実装を行うことができる

簡単な制御用関数

// if letのなかではOptional型しか扱えないので、
// 通常の変数を扱うためにOptional型でくるんでやる
func let_<T>(s:T) -> T?{
    return s
}

// if文に相当する分岐
func if_<T>(b:Bool, #then:()->T, #els:()->T) -> T{
    if b {
        return then()
    }else{
        return els()
    }
}

// あとはfor文に相当する処理とか

func getC(c:String) -> String? {
    return c + "C"
}

func test(arg:String) -> String? {
    if let
        a = let_(arg), // 引数をoptional化
        b = if_(a == "A", // 条件分岐
            then:{
                return a + "B"
            },els:{
                return nil
            }),
        c = getC(b)
    {
        return c
    }
    return nil
}


test("A") // => "ABC"
test("B") // => nil

これってHaskell的には

Maybeモナドのdo構文とそっくりですね