Swiftのguard文を解説!初心者が知るべき10の使い方とサンプルコード

初心者向けにSwiftのguard文を詳しく解説した記事のサムネイルSwift

 

【当サイトはコードのコピペ・商用利用OKです】

このサービスはASPや、個別のマーチャント(企業)による協力の下、運営されています。

記事内のコードは基本的に動きますが、稀に動かないことや、読者のミスで動かない時がありますので、お問い合わせいただければ個別に対応いたします。

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればカスタムコードを使って機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10000時間以上』を満たすプログラマ集団によって監修されています。

はじめに

Swiftのプログラミング言語は、近年非常に人気があり、多くのiOSアプリ開発者やMacアプリ開発者に支持されています。

Swiftには多くの独自の機能や文法があり、その中でも「guard文」は非常に特徴的で役立つ機能の一つとして知られています。

この記事では、Swiftの「guard文」について、初心者が知るべき使い方やサンプルコードを中心に、徹底的に解説していきます。

Swiftのプログラミングに携わるすべての方に、guard文の基本的な使い方から応用例、注意点、カスタマイズ方法まで幅広く紹介していきますので、ぜひ最後までお読みください。

●Swiftとは

Swiftは、Appleが2014年に発表した新しいプログラミング言語であり、iOSやmacOSなどのアプリケーションを開発するための言語として、従来のObjective-Cに代わるものとして設計されました。

Swiftは安全性と性能の向上を目指して開発され、多くの開発者に迅速に受け入れられました。

○Swiftの特徴と人気の理由

Swiftには、次のような特徴があります。

  1. 高速:Swiftは高性能なコンパイラ技術を取り入れているため、実行速度が非常に高いです。これにより、リアルタイムでのアプリケーションの動作や、高負荷の処理でもスムーズに動作します。
  2. 安全性:Swiftの言語設計は、安全性を最優先に考えています。このため、変数の未初期化の参照やnull参照のエラーなど、多くの一般的なプログラミングミスをコンパイル時に検出することができます。
  3. 読みやすさ:Swiftの文法は直感的でシンプルであり、初心者でも学びやすいのが特徴です。また、英語に近い自然な文法のため、コードが読みやすく、理解しやすいです。
  4. 現代的な言語設計:Swiftは最新のプログラミング言語設計の理念を取り入れており、関数型プログラミングやジェネリクスなどの先進的な特徴を備えています。

これらの特徴から、Swiftは多くの開発者に支持され、特にiOSアプリの開発においては主要な言語として位置づけられています。

また、Swiftのコミュニティは活発であり、多くのライブラリやフレームワークが公開されているため、様々な開発ニーズに応えることができます。

●guard文とは

Swiftのプログラミングを学び進める中で、guard文は非常に重要な構文の1つとなります。

guard文は、特定の条件が満たされていない場合に早期に関数やメソッドの実行を終了させるための構文です。

これにより、不要なネストや冗長なコードを避けることができ、コードの可読性を高めることができます。

○guard文の基本概念

guard文は、次のような基本的な構造を持っています。

guard 条件式 else {
    // 条件式がfalseのときの処理
    return // または、break, continue, throwなど
}

このコードでは、条件式trueであれば、guard文の後のコードが通常通り実行されます。

しかし、条件式falseの場合、elseブロック内のコードが実行されます。

このとき、returnbreakcontinuethrowなどの制御転送ステートメントを用いて、現在のコンテキスト(関数、メソッド、ループなど)からの脱出が必要となります。

○guard文のメリット

guard文を使用する最大のメリットは、コードのネストを減少させることで、コードの可読性を向上させることができる点にあります。

特に、複数の条件をチェックする必要がある場合や、Optional値のアンラップを行う場面での利点が大きいです。

  1. 早期リターン:guard文を使うことで、特定の条件が満たされない場合に関数やメソッドの実行を早期に終了させることができます。これにより、後続のコードではその条件が満たされていることが保証されるため、安全にコードを実行することができます。
  2. コードの整理:条件分岐の際、if文を多用するとコードがネストしやすくなります。これにより、コードが読みにくくなることがあります。guard文を使用することで、このネストを避け、スッキリとしたコードを書くことができます。
  3. 明示的な意図の表現:guard文を使用することで、特定の条件が満たされていない場合の早期リターンを明示的に表現できます。これにより、他の開発者がコードを読む際に、その意図を容易に理解することができます。

●guard文の使い方

Swiftのguard文はコードの可読性を向上させ、早期リターンを行う際に特に役立ちます。

ここでは、guard文の基本的な使い方から少し応用的な使い方までをサンプルコードとともに詳しく解説します。

○サンプルコード1:基本的なguard文の使用方法

guard文は条件式が真の場合にコードの実行を続行し、偽の場合には指定されたブロック内での早期リターンを実行します。

ここでは、guard文の基本的な使用方法を表すサンプルコードを紹介します。

func checkValue(value: Int?) {
    guard let unwrappedValue = value, unwrappedValue > 0 else {
        print("値が不正です。")
        return
    }
    print("値は\(unwrappedValue)です。")
}

このコードでは、Optionalの整数を受け取り、その値が正の整数であるかどうかを確認します。

この例では、Optionalのアンラップと整数の範囲チェックを同時に行っています。

正の整数である場合、値を出力し、そうでない場合はエラーメッセージを出力して関数から早期にリターンします。

このコードを実行すると、例えばcheckValue(value: 5)とした場合、コンソールには「値は5です。」と出力されます。

一方で、checkValue(value: -3)checkValue(value: nil)とした場合には、「値が不正です。」と表示されます。

○サンプルコード2:Optionalのアンラップにguard文を使用

Optional型の変数や定数をアンラップする際に、guard文を使用することで安全に値を取り出すことができます。

下記のサンプルコードは、Optionalの文字列を受け取り、その文字列が空でないことを確認するものです。

func checkString(input: String?) {
    guard let unwrappedInput = input, !unwrappedInput.isEmpty else {
        print("文字列が空またはnilです。")
        return
    }
    print("文字列は\(unwrappedInput)です。")
}

このコードでは、Optionalの文字列を受け取り、その文字列が空でないかどうかを確認します。

この例では、Optionalのアンラップと文字列の空チェックを同時に行っています。

空でない場合、文字列を出力し、空またはnilの場合はエラーメッセージを出力して関数から早期にリターンします。

このコードを実行すると、例えばcheckString(input: "Hello")とした場合、コンソールには「文字列はHelloです。」と出力されます。

一方で、checkString(input: "")checkString(input: nil)とした場合には、「文字列が空またはnilです。」と表示されます。

○サンプルコード3:guard文での早期リターン

guard文の最も一般的な使い方は、条件が満たされない場合の早期リターンです。

条件が満たされない場合に、関数やメソッドの処理を早期に終了させることができます。

このコードでは、関数内でguard文を使って条件をチェックし、その条件が満たされない場合には早期リターンしています。

func checkAgeForDrivingLicense(age: Int?) {
    // 年齢が入力されているか、そして18歳以上であるかを確認
    guard let verifiedAge = age, verifiedAge >= 18 else {
        print("運転免許を取得するには、18歳以上である必要があります。")
        return
    }
    print("運転免許を取得することができます!")
}

checkAgeForDrivingLicense(age: 16) // 16歳の場合

この例では、年齢をチェックして18歳以上であるかを確認しています。

16歳の場合、条件は満たされず、”運転免許を取得するには、18歳以上である必要があります。”と表示されます。

○サンプルコード4:guard文とif文の違い

guard文とif文は条件チェックに使用されるSwiftの文法ですが、役割や使い方に違いがあります。

ここでは、その違いを明確にするためのサンプルコードを紹介します。

func guardVsIfExample(value: Int?) {
    // guard文
    guard let verifiedValue = value, verifiedValue > 10 else {
        print("guard文: 値は10以下です。")
        return
    }
    print("guard文: 値は10より大きいです。")

    // if文
    if let verifiedValue = value, verifiedValue > 10 {
        print("if文: 値は10より大きいです。")
    } else {
        print("if文: 値は10以下です。")
    }
}

guardVsIfExample(value: 5) // 5の場合

この例では、5をチェックして10より大きいかを確認しています。

5の場合、guard文では”値は10以下です。”と表示され、if文でも同様のメッセージが表示されます。

○サンプルコード5:guard文のネスト

guard文は、複数の条件を順番にチェックする場合にネストして使用することができます。

このコードでは、ネストしたguard文を使って複数の条件をチェックしています。

func nestedGuardCheck(value1: Int?, value2: Int?) {
    guard let verifiedValue1 = value1, verifiedValue1 > 5 else {
        print("value1は5より大きくなければなりません。")
        return
    }

    guard let verifiedValue2 = value2, verifiedValue2 < 20 else {
        print("value2は20より小さくなければなりません。")
        return
    }

    print("両方の条件が満たされました。")
}

nestedGuardCheck(value1: 10, value2: 15) // 10と15の場合

この例では、value1が5より大きいか、value2が20より小さいかをチェックしています。

10と15の場合、”両方の条件が満たされました。”と表示されます。

●guard文の応用例

Swiftのguard文は基本的な使い方だけでなく、より高度な使い方や応用例も多数存在します。

ここでは、guard文を応用したいくつかのサンプルコードを紹介します。

○サンプルコード6:guard文を使った複雑な条件チェック

実際のアプリケーション開発においては、複数の条件を同時にチェックする必要が出てくることがよくあります。

このような場合にguard文をうまく活用することで、コードの読みやすさや保守性を向上させることができます。

func userEligibility(age: Int?, hasPermission: Bool?) {
    guard let userAge = age, userAge >= 18, let permission = hasPermission, permission else {
        print("利用資格がありません")
        return
    }
    print("利用資格があります")
}

このコードでは、ユーザーがサービスの利用資格を持っているかどうかをチェックしています。

年齢が18歳以上であり、かつ利用許可があるかどうかを同時に確認しています。

guard文を使うことで、条件を一元化してチェックすることができ、コードがすっきりとします。

上記のコードを実行する場合、次のような結果になります。

ユーザーの年齢が19歳で、利用許可がある場合

利用資格があります

ユーザーの年齢が17歳で、利用許可がある場合

利用資格がありません

○サンプルコード7:guard文とエラーハンドリング

Swiftにはエラーハンドリングのための仕組みが提供されています。

このエラーハンドリングとguard文を組み合わせることで、より堅牢なコードを実現することができます。

ここでは、エラーハンドリングとguard文を組み合わせたサンプルコードを紹介します。

enum AccountError: Error {
    case invalidUsername
    case invalidPassword
}

func login(username: String?, password: String?) throws {
    guard let user = username, !user.isEmpty else {
        throw AccountError.invalidUsername
    }
    guard let pass = password, pass.count >= 8 else {
        throw AccountError.invalidPassword
    }
    print("ログイン成功")
}

このコードでは、ユーザーネームとパスワードの正当性をチェックしています。どちらかが不正な場合、適切なエラーを投げるようにしています。

guard文とエラーハンドリングを組み合わせることで、エラーの原因を明確にし、その場で処理を中止することができます。

このコードの実行結果として、次のような場面を想定できます。

ユーザーネームがnilまたは空文字の場合

エラー: invalidUsername

パスワードが8文字未満の場合

エラー: invalidPassword

正しいユーザーネームとパスワードが与えられた場合

ログイン成功

○サンプルコード8:guard文とSwiftの関数

Swiftで関数を定義する際、引数の値を安全に取り扱いたいときにguard文が役立ちます。

特に、引数がOptional型の場合、関数内部でその値をアンラップして安全に使用するのにguard文は適しています。

例を通して見てみましょう。

func greet(name: String?) {
    // 名前がnilでないことを確認
    guard let unwrappedName = name else {
        print("名前が指定されていません。")
        return
    }
    print("こんにちは、\(unwrappedName)さん!")
}

このコードでは、関数greetにOptional型の引数nameを渡しています。

guard文を使用して、nameがnilでないことを確認してから、その値をunwrappedNameとして利用しています。

もしnameがnilだった場合、エラーメッセージを表示して関数を早期に終了しています。

この例を実際に実行してみると、次のような結果が得られます。

名前を指定して関数を呼び出す場合、

greet(name: "太郎")

結果として”こんにちは、太郎さん!”となります。

名前を指定しない場合、

greet(name: nil)

結果として”名前が指定されていません。”となります。

○サンプルコード9:guard文と配列

Swiftの配列に対して、特定のインデックスの要素を安全に取得するためにもguard文を使用することができます。

例えば、配列の中の指定されたインデックスの要素が存在するかを確認して、存在する場合のみその要素を利用するシチュエーションを考えてみましょう。

func getFruit(from fruits: [String], at index: Int) {
    // 指定されたインデックスが配列の範囲内にあるか確認
    guard index < fruits.count else {
        print("インデックスが配列の範囲を超えています。")
        return
    }
    print("選ばれた果物は\(fruits[index])です。")
}

このコードでは、関数getFruitに配列fruitsとインデックスindexを渡しています。

guard文を使用して、指定されたインデックスが配列の範囲内に存在するかを確認しています。

範囲外の場合、エラーメッセージを表示して関数を早期に終了しています。

この例を実際に実行してみると、次のような結果が得られます。

適切なインデックスを指定して関数を呼び出す場合、

let fruits = ["りんご", "みかん", "ぶどう"]
getFruit(from: fruits, at: 1)

結果として”選ばれた果物はみかんです。”となります。

範囲外のインデックスを指定する場合、

getFruit(from: fruits, at: 5)

結果として”インデックスが配列の範囲を超えています。”となります。

○サンプルコード10:guard文のカスタムエラーメッセージ

guard文の条件が満たされない場合に実行されるブロックの中で、カスタムエラーメッセージを表示することも可能です。

エラーメッセージをカスタマイズすることで、デバッグが容易になるだけでなく、ユーザーにもより具体的な情報を提供することができます。

例を通して見てみましょう。

func calculateAge(birthYear: Int?) {
    // 出生年がnilでなく、かつ範囲内であることを確認
    guard let year = birthYear, year > 1900 && year <= 2023 else {
        print("無効な出生年が指定されました。")
        return
    }
    let age = 2023 - year
    print("あなたの年齢は\(age)歳です。")
}

このコードでは、関数calculateAgeにOptional型の引数birthYearを渡しています。

guard文を使用して、birthYearがnilでないことと、出生年が有効な範囲内であることを確認しています。

条件が満たされない場合、カスタムエラーメッセージを表示して関数を早期に終了しています。

この例を実際に実行してみると、次のような結果が得られます。

正しい出生年を指定して関数を呼び出す場合、

calculateAge(birthYear: 2000)

結果として”あなたの年齢は23歳です。”となります。

無効な出生年を指定する場合、

calculateAge(birthYear: 1890)

結果として”無効な出生年が指定されました。”となります。

●注意点と対処法

Swiftのプログラミングにおいて、guard文は非常に便利な構文の一つです。

ここでは、特に初心者の方々が直面する可能性のあるguard文の使用上の注意点と、それに対する対処法について詳細に解説します。

Swiftにおけるguard文の適切な使い方を理解し、効果的にコードに組み込むことで、より安全で読みやすいプログラムを作成することができます。

○guard文の使用上の注意

guard文はSwiftのプログラミングにおいて、条件が満たされない場合に早期に処理を中断するために用います。

これは特にOptional値の取り扱いや条件付きのロジックにおいて非常に有効です。

しかし、この便利なguard文を使用する際には、いくつかの注意点があります。

□条件の明確性

guard文を使用する際は、条件が非常に明確であることが重要です。

複雑な条件は読み手にとって理解しにくく、バグの原因になりやすいです。

条件はシンプルかつ明瞭に保つことが望ましいです。

□早期リターン

guard文は、条件が満たされない場合にそのスコープから抜け出すためにreturnbreakcontinuethrowなどを用いて早期リターンを行います。

この早期リターンを忘れると、コンパイルエラーの原因になります。

□過度な使用

guard文は非常に有用ですが、過度に使用するとコードの可読性を低下させる可能性があります。

条件のチェックは必要な箇所に限定し、適切なバランスを保つことが重要です。

○guard文のよくあるトラブルとその対処法

guard文を使用する際に発生しやすいトラブルとしては、主に次のようなものがあります。

□条件式の誤り

条件式が意図しないものであったり、誤っていたりすると、プログラムが予期しない動作をする原因になります。

これを防ぐためには、条件式を慎重に検討し、テストを十分に行うことが必要です。

□早期リターンの見落とし

guard文では条件が満たされない場合にスコープを抜けるためのリターンが必要ですが、これを忘れるとコンパイルエラーになります。

エラーメッセージをよく読み、適切なリターン文を書くことが大切です。

□過度のネスト

guard文を多用することでコードが深くネストされ、読みにくくなることがあります。

この問題を避けるためには、関数を小さく分割するなどして、guard文の使用を適切に調整することが効果的です。

●guard文の拡張やカスタマイズの方法

Swiftのguard文はその基本的な使い方だけでなく、実際の開発現場ではさまざまなカスタマイズや拡張が可能です。

ここでは、guard文を更に活用するためのカスタマイズ方法や拡張の方法について解説します。

○guard文のカスタムエラーメッセージの作成

guard文を使用する際には、条件が満たされなかった場合にエラーメッセージを出力することが一般的です。

しかし、エラーメッセージをカスタマイズすることで、より具体的な情報をユーザーや開発者に提供することができます。

例えば、次のコードでは、guard文を使用して文字列が数字のみから成るかをチェックしています。

数字のみでない場合にはカスタムエラーメッセージを出力します。

func checkNumericValue(value: String) {
    guard value.rangeOfCharacter(from: CharacterSet.decimalDigits.inverted) == nil else {
        // カスタムエラーメッセージの出力
        print("エラー: \(value) は数字のみではありません。")
        return
    }
    print("\(value) は数字のみから成る文字列です。")
}

checkNumericValue(value: "12345")  // 12345 は数字のみから成る文字列です。
checkNumericValue(value: "12abc")  // エラー: 12abc は数字のみではありません。

この例では、数字のみから成る文字列かどうかを確認しています。

数字のみでない場合にはカスタムエラーメッセージが出力され、どのような文字列がエラーの原因となったのかが明示されます。

○guard文の拡張を利用した複雑な条件のチェック

Swiftでは、拡張機能を使用して既存の型やクラスに新しい機能を追加することができます。

この拡張機能を利用してguard文を拡張し、複雑な条件チェックを簡潔に記述することができます。

例えば、String型に「isValidEmail」という新しいメソッドを追加して、メールアドレスの形式が正しいかどうかをチェックすることができます。

extension String {
    var isValidEmail: Bool {
        let regex = "[A-Z0-9a-z._%+-]+@[A-Z0-9a-z.-]+\\.[A-Za-z]{2,64}"
        return NSPredicate(format: "SELF MATCHES %@", regex).evaluate(with: self)
    }
}

func checkEmail(email: String) {
    guard email.isValidEmail else {
        print("無効なメールアドレス: \(email)")
        return
    }
    print("\(email) は有効なメールアドレスです。")
}

checkEmail(email: "test@example.com")  // test@example.com は有効なメールアドレスです。
checkEmail(email: "test@example")      // 無効なメールアドレス: test@example

この例では、「isValidEmail」メソッドを使用してメールアドレスの形式が正しいかどうかを簡単にチェックしています。

正しくない場合にはカスタムエラーメッセージが出力されます。

まとめ

Swiftのguard文は、条件が満たされない場合に早期リターンを行うための強力なツールです。

基本的な使い方から応用例、カスタマイズ方法まで、さまざまなシチュエーションでの利用法を学ぶことができたかと思います。

特に、カスタムエラーメッセージの作成や拡張機能を利用した複雑な条件のチェックは、実際の開発現場での応用範囲が広いため、ぜひ覚えておきたいポイントです。

また、guard文を使用することで、コードの可読性や安全性が向上します。

条件が満たされない場合の処理を先に記述することで、その後のコードでは条件が満たされていることが保証されるため、エラーハンドリングが簡単になります。

この記事を通じて、Swiftのguard文の使いこなし方やその可能性について深く理解することができたことを願います。

実際の開発においても、guard文を効果的に使用して、より品質の高いアプリケーションの開発を目指しましょう。