【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/

【Swift】関数

関数とは処理をまとめて名前をつけたもので、入力を取って処理(演算)したり、任意のタイミングで同じ処理を再利用したりする事ができるものです。また、処理した値を出力することもできます。
引数と戻り値、返り値について
入力の事を引数、出力の事を戻り値、または返り値と言います。

前回は 配列型 について書きました。

今回は 関数 について書いていこうと思います。

関数とは

関数とは処理をまとめて名前をつけたもので、入力を取って処理(演算など)したり、任意のタイミングで呼び出して同じ処理を再利用する事ができるものです。また、処理した値を出力することもできます。

引数と戻り値(返り値)について

入力の事を引数、出力の事を戻り値、または返り値と言います。
関数に引数が必要ない場合、戻り値が必要ない場合は省略する事ができます。

関数の書式

引数が必要ない場合、戻り値が必要ない場合の書式

funk 関数名() {
     処理(ローカルスコープ)
 }

関数は頭に func キーワードを付けます。
関数名の後に ( ) だけ書いて、中括弧 { } の中に処理を書きます。

引数を取って戻り値を返したい場合の書式

funk 関数名(引数名:型名(入力の型),...) -> 戻り値(出力)の型名 {
     処理(ローカルスコープ)
     return 戻り値(出力)
 }

関数名を書いた後 ( ) を書いて、中に 引数名入力の型名 を書きます。
引数名型名 はコロン : で区切ります。
引数を複数書く場合は、カンマ , で区切ります。
矢印のような記号は、ハイフン と大なり > 記号になっていて、アロー演算子と言います。
アロー演算子 -> の後に 出力(戻り値)の型名 を書いて、 { } の中に処理を書きます。
処理の最後に return キーワードを書いて、出力(戻り値)の型 と同じ型の値を返します。

関数の書き方

引数が必要ない場合、戻り値が必要ない場合の例

//引数が必要ない場合、戻り値が必要ない場合の例
func greeting() {
    var a = "Hello.Swift!"
    print(a)
}

ただ文字列を出力するだけの関数で引数も戻り値も必要無いので、こういった場合は省略できます。

この関数を実行するときの例

//引数が必要ない場合、戻り値が必要ない場合の例
func greeting() {
    var a = "Hello.Swift!"
    print(a)
}
//実行例
greeting() //Hello.Swift!
functionコードimg2

引数を取って戻り値を返したい場合の例と実行例

//引数を取って戻り値を返したい場合の例
func calculation(a:Int, b:Int) -> Int {
    let result = a + b
    return result
}

この例は Int型 の 引数 a と、Int型の 引数 b を宣言して、 ab に入力された値を演算し、その結果を Int型 で返すというだけの関数です。
return で返したい戻り値の型と、 -> の戻り値の型名の所は同じ型でなければエラーになります。

この関数を実行するときの例

//引数を取って戻り値を返したい場合の例
func calculation(a:Int, b:Int) -> Int {
    let result = a + b
    return result
}

//実行例
var c = calculation(a: 1, b: 2)
print(c) //3

関数calculation の 引数 ab にそれぞれ 12 を入力して演算された結果を 変数 c に代入しています。
関数の処理の内容は a + b と足し算になっているので、1 + 2 の演算結果が 変数 c に代入されます。

数値型の演算 についてはこちらで紹介しています。

functionコードimg

この他に引数あり戻り値なしのパターンや、引数なし戻り値ありで書くこともできます。
引数がない関数はいつどこで呼び出そうと処理が同じなので汎用性は低いと思いますが、任意のタイミングで同じ処理を複数回したい場合などは、一度定義しておけば後は呼ぶだけなのでコード量も減らせて可読性も良くなると思います。
以上 関数 についてでした。

次回は 構造体 について書いていこうと思います。

実行環境

version
Xcode 14.2 (14C18)
Swift 5.2.4

公式ドキュメント

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