【Swift】guard文とguard-let文

guard文とは条件を満たさない場合の処理を書く構文で、コードを安全にするために使います。
if-else文でも同様のことはできますが、guard文は条件を満たさない場合のみの処理を書くことができます。
安全にメソッドの処理を途中で終了(return)したいとき、ループ処理の中断(break)したいときなどに使います。

前回は break文 と continue文 について書きました。

今回は guard文 について書いていこうと思います。

guard文

guard文 とは

guard文 とは条件を満たさない場合の処理を書く構文で、コードを安全にするために使います。
if-else文 でも同様のことはできますが、guard文 は条件を満たさない場合のみの処理を書くことができます。
安全にメソッドの処理を途中で終了( return )したいとき、ループ処理を中断( break )したいときなどに使います。

guard文 の書式

 guard 条件 else{
     処理
     return または break
 }

guard文 は基本的に関数内や制御構文内に書きます。
guard キーワードの後に条件を書いて、その後に else キーワードをつけます。
{ } の中に処理を書きますが、処理は条件が false だった場合に実行されます。
関数や制御構文のスコープを抜けるために return または break などが必要です。

guard文 を使った例

let slot = [145, 214, 405, 315, 777, 343]
let stop = slot.randomElement() ?? 123

func jackpot(num: Int){
    guard num == 777 else{
        print("\(num) ハズレ:関数から抜けます。")
        return
    }
    print("\(num) 大当たり!")
}

jackpot(num: stop)

配列slot に 3 桁の整数を要素として複数代入しています。
配列slot の要素の中からランダムに要素を取り出して、定数stop に代入します。

関数jackpot を定義し Int型 の引数を取って、引数の値によって処理を分岐します。
guard文 の条件は 引数num の値が 777 ではなかったらguard文 の処理が実行されて、return ( 関数から抜ける )します。これを 早期リターン と言います。
引数num の値が 777 だったらguard文 の条件から外れるので、return されずに次の print( ) が実行されアンラップした値を出力します。

randomElement( ) メソッドはコレクション型の要素をランダムに返すメソッドです。返ってくる値は Optional型 なのでアンラップして 定数stop に代入しています。

関数jackpot の引数に 定数stop を指定して実行してみます。

let slot = [145, 214, 405, 315, 777, 343]
let stop = slot.randomElement() ?? 123

func jackpot(num: Int){
    guard num == 777 else{
        print("\(num) ハズレ:関数から抜けます。")
        return
    }
    print("\(num) 大当たり!")
}

jackpot(num: stop)

//実行結果
/*
145 ハズレ:関数から抜けます。
*/

ランダムに取り出された要素が 145 でした。
条件が false になるので、guard文 の処理を実行して return されます。
return されている( 関数から抜けている )ので、下の print( ) は実行されません。

guardコードimg

次は 777 だった場合の実行結果を見てみます。

let slot = [145, 214, 405, 315, 777, 343]
let stop = slot.randomElement() ?? 123

func jackpot(num: Int){
    guard num == 777 else{
        print("\(num) ハズレ:関数から抜けます。")
        return
    }
    print("\(num) 大当たり!")
}

jackpot(num: stop)

//実行結果
/*
777 大当たり!
*/

777 だった場合は、guard文 の条件から外れているので return されず下の print( ) が実行されます。

guardコードimg2

guard-let文

guard-let文 とは

guard-let文 とはオプショナルバインディングの 1 つで、Optional型 をアンラップするときに使います。
if-let文 でもアンラップすることができますが、if-let文スコープ内でのみアンラップした定数を使うことができるのに対し、guard-let文スコープの外でも定数を使うことができます。

guard-let文 の書式

guard let 定数名 = Optional型の値 else{
     アンラップに失敗した場合の処理
     return または break
 }

guard-let文guard文 同様、基本的に関数内や制御構文内に書きます。
guard let キーワードの後に定数名を書いて、アンラップしたい Optional型の値 の後に else キーワードを付けます。
{ } の中は、if-let文 と違い、Optional型の値 をアンラップ失敗した場合の処理を書きます。
アンラップ失敗したときの処理なので、スコープを抜けるために return または break などが必要です。

guard-let文 を使った例

let aHalf = ["1", nil, "2", nil, "3", nil]
print(type(of: aHalf)) //Array<Optional<String>>
let stop = Int.random(in: 0 ..< aHalf.count)

func judgement(){
    guard let unwrap = aHalf[stop] else{
        print("nil 関数から抜けます。") //nilだった場合
        return
    }
    print("\(unwrap)") //nilでなければアンラップして出力

}

judgement()

配列aHalfString型 の要素と、nil を 3 つずつ代入しています。
この配列は nil も代入されているので、Optional<String> 型 の配列になります。
random(in:) メソッドを使って、0 ~ 9 の中からランダムに返された値を 定数stop に代入します。
この 定数stop の値をインデックス番号として使います。

関数judgement を定義し、処理で guard-let文 を使って 配列aHalf の要素をアンラップしていきます。
ランダムに選択された aHalf[stop] の値が、アンラップ失敗( 値が nil )であれば、“nil 関数から抜けます。” と出力し return で関数を抜けます。
aHalf[stop] の値がアンラップ成功であれば、guard-let文 の条件から外れるので、return されずに 次の print( ) が実行されて、アンラップされた値を出力します。

if-else文 ではスコープ内に定義した定数はスコープ内でしか使えませんでしたが、guard-let文スコープ外でもアンラップした定数が使う事ができます。

random(in:) は、指定された範囲内でランダムな値を返すメソッドです。
Int.random(in: 0 ..< aHalf.count) とすると、0 から 配列aHalf の要素数 6 ( 6 は含まない ) となるので 0 ~ 5 の中からランダムな整数が返されます。

guardコードimg3

以上 guard文 についてでした。

次回は switch文 について書いていこうと思います。

実行環境

version
Xcode 14.2 (14C18)
Swift 5.2.4

公式ドキュメント

https://docs.swift.org/swift-book/documentation/the-swift-programming-language/