50
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

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

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構文とそっくりですね

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
50
Help us understand the problem. What are the problem?