Swift guard文による早期退出

Swiftには条件不成立時に早期退出するための条件分岐文として、guard文が用意されています。
Bool値の値を元に処理を分岐させる制御構文という点はif文と同じですが、その用途や制約が異なります。
今回はそんなguard文についてまとめていきたいと思います。

guard文とは

guard文とは、ある条件を判定し不成立の場合に強制的に早期退出させる条件分岐文です。
早期退出とは、スコープ内の処理を強制的に終了させそれ以降の処理を行わずに結果を返却することです。
guard文があることによって、条件不成立時に強制的に早期退出するため、以降の処理では条件が必ず成り立つことが保証されます。

guard文の基本文法

guard文の基本文法は以下の通りです。

guard 条件式 else {
    条件不成立時に実施する処理
    早期退出による結果の返却
}

... 後続処理(条件式が成り立つことが保証される)

guard文の分岐内の処理ではそのguard文が含まれるスコープからの早期退出による結果の返却を必ず行わなければなりません。
guard文の処理では早期退出が行われているかがコンパイラによってチェックされ、行っていない場合はコンパイルエラーとなります。

guard文の利用

guard文以降の処理で条件が成立することを保証する

guard文があることによって後続処理で条件の成立を保証することができます。
下記の例ではgurad文で引数numを正の数かを判定し後続処理で正の数であることを前提とした処理を行なっています。

func printPositiveNum(_ num: Int) {
    guard num > 0 else {
        print("not positive")
        return // スコープprintPositiveNumから早期退出
    }
    print("positive number : " + num)
}

printPositiveNum(-1) // >>> not positive
printPositiveNum(3) // >>> positive number : 3 

guard let文による値の存在の保証と定数定義

guard文にもif文と同じようにguard let文が存在し、値の代入可否が定かではない定数を定義することが可能です。
guard let文の場合、宣言した定数の値が代入不可の場合に分岐処理内に入り早期退出をします。
また、if let文の場合は条件分岐処理内のスコープでのみ定数は参照可能でしたが、guard let文の場合はguard文以降の処理では値の代入が保証されるため宣言した定数にアクセス可能となります。

func twiceStringNum(_ strNum: String) -> Int {
    guard let num = Int(strNum) else {
        print("数値ではありません")
        return -1
    }
    // guard文以降の処理で定数numにアクセス可能
    return num * 2
}

print(twiceStringNum("3"))
// >>> 6
print(twiceStringNum("str"))
// >>> 数値ではありません
// >>> -1

上記の例では文字列型の引数strNumをInt型に変換し代入可能か判定し、不可能な場合はメッセージ出力をして-1の結果を返却し早期退出させています。
Int型に変換可能であった場合、guard文以降の処理に移り引数の数値を二倍した値を返却しています。

if文との使い分け

上記の例はif文でも実装可能ですが、guard文には強制的に早期退出させるという特徴があります。
そのため条件が成立しない場合に処理を行いたくない場合や、条件が保証されていることを表現したい場合などはguard文を利用して記述した方がわかりやすく、コンパイラによって早期退出されているかが監視され単純なミスを減らすこともできます。

まとめ

  • guard文は条件が不成立の場合に強制的に早期退出をさせる条件分岐文
  • 基本文法:guard 条件式 else { 不成立の場合の処理と早期退出処理 }
  • guard文による変数宣言:guard let 変数名 = 代入可否が定かでない値 else { 代入不可の場合の処理と早期退出処理 }
  • 強制的に早期退出をさせる特徴から処理の条件の保証を表現するのに適している

今回、guard文についてまとめてきましたが、筆者はこのような条件分岐ぶんはSwiftで初めて見ました。
確かに普段コードを書く上で処理の前提条件を最初に判定することはよくあります。
gurad文はそのような場合を明示的に示すことができ、コンパイラによる早期退出のチェックも入るので、理解した上で使うことができれば可読性と品質の向上につながることが考えられます。
適切に利用できるよう心がけていきたいですね。

ここまで読んでいただきありがとうございました。
それでは、また。