SwiftでNullの判定をするための10選 – Japanシーモア

SwiftでNullの判定をするための10選

Swift言語のロゴとNullの記号がデザインされた画像Swift
この記事は約23分で読めます。

 

【サイト内のコードはご自由に個人利用・商用利用いただけます】

このサービスは複数のSSPによる協力の下、運営されています。

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

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

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

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

Swift言語、それは近年のプログラミング界で急速に普及しているAppleの公式言語です。

iOSやmacOSなどの開発に使われるこの言語は、その高速性や安全性から多くの開発者に支持されています。

しかし、プログラミングにおいては、さまざまなデータの扱いが重要となる中、Nullの判定は特に避けては通れないテーマとなっています。

この記事を読めばNull判定をSwiftで行う方法を習得できます。特にSwift初心者の方々にとって、Nullの取り扱いは少し難しく感じるかもしれません。

そこで、この記事ではSwiftでのNull判定方法を10の具体的な手法とサンプルコードを交えて詳しく解説します。

一つ一つの手法を理解し、実践していくことで、SwiftのNull判定のプロフェッショナルへとステップアップしていきましょう。

●Swiftとは?

Swiftは、Appleが2014年に発表したプログラミング言語です。

Objective-Cの後継として位置づけられ、iOSやmacOS、watchOS、tvOSといったAppleのプラットフォーム向けのアプリケーション開発に用いられます。

○Swiftの基本的な特徴

Swiftは、次のような特徴を持つ言語として設計されています。

  • 安全性:エラーを生じにくいような設計がなされている。
  • 高速性:最適化されたコンパイラを持ち、実行速度が速い。
  • モダン:直感的な構文を持ち、初心者にも読みやすい。
  • 強力な型システム:変数の型をしっかりと定義することで、バグを未然に防ぐ。

○Swiftが支持される理由

多くのプログラマーがSwiftを好む理由として次の点が挙げられます。

  • Appleの公式言語:Appleの公式言語としてサポートが強化されているため、安心して学習・開発ができる。
  • オープンソース:Swiftはオープンソースとして公開されており、コミュニティが活発に成長している。
  • 幅広い対応プラットフォーム:iOSやmacOSはもちろん、Linuxなどのプラットフォームでも動作する。
  • Playgroundの提供:実際にコードを書きながら動きを確認できる環境が提供されているため、学習が効率的に行える。

●Null判定の重要性

プログラミングにおけるNullは、特定の変数やデータが「何も値を持っていない」ことを表す特殊な値です。

Nullは「存在しない」、「未定義」、「値が不明」などの状態を表すために使用されます。

しかし、Nullを適切に扱わないと、プログラム上で予期せぬエラーやバグを引き起こす可能性があります。

○プログラムにおけるNullの役割

Nullは、データが存在しないことを示す重要な手段として、多くのプログラム言語で使われています。

例えば、データベースから情報を取得する際、該当するデータが存在しない場合、Nullという値が返されることが一般的です。

また、変数を初期化せずに使用しようとしたときや、関数が何も返さない場合など、様々な状況でNullが用いられます。

○Null判定が必要な場面

Nullの存在が表す「データの欠如」は、そのまま放置すると多くのトラブルの原因となります。

ここでは、Null判定が必要とされる主な場面を紹介します。

  1. データベースのクエリ結果:データベースからデータを取得する際、該当するデータがない場合、Nullが返されます。このNullを適切に処理しないと、後続の処理でエラーが発生する可能性があります。
  2. APIのレスポンス:外部のAPIを利用してデータを取得する際、APIの仕様やネットワークの状況により、期待するデータがNullとして返されることがあります。
  3. 未初期化の変数:変数を宣言したが、初期化せずに使用した場合、その変数はNullを持つ可能性があります。このNullをそのまま処理に使ってしまうと、エラーが発生することが考えられます。

●SwiftにおけるNull判定の基本

SwiftのNull判定は他の多くのプログラミング言語とは少し異なります。

Swiftでは、Nullのことを「nil」と呼びますが、直接的なnilの代入やチェックよりも、Optional型という特有の型を使って値の有無を扱います。

○Optionalとは?

SwiftにおけるOptionalは、変数が値を持つか、もしくは持たない(nil)場合の2つの状態を表現するための特別な型です。

Optional型を使うことで、変数が必ずしも値を持つとは限らないことを明示的に表現することができ、これによりプログラムの安全性が向上します。

例えば、整数値を持つかもしれない、持たないかもしれない変数を宣言する場合は次のようにします。

var number: Int? // Int型のOptional

この変数numberは、Int型の値を持つこともあれば、何も持たない状態(nil)であることも考えられます。

○Optionalの基本的な使い方

Optional型の変数を宣言した後、実際の値を代入する場合や、その値を取り出す場合には特別な方法が必要です。

1.Optional型の変数への代入

Optional型の変数には、通常の値の代入の他に、nilの代入も可能です。

var name: String? 
name = "山田"  // 値を代入
name = nil    // nilを代入

2.Optional型の変数からの値の取り出し

Optional型の変数から値を取り出す場合、強制的にアンラップする方法や、安全にアンラップする方法など、いくつかの方法があります。

強制的にアンラップする方法は、プログラムがクラッシュする原因となるため、注意が必要です。

var age: Int? = 25

let unwrappedAge1 = age!  // 強制的にアンラップ(注意が必要)

このコードのage!の部分で、ageの持つ値を強制的に取り出しています。

もしageがnilの場合、このコードはランタイムエラーとなります。

●SwiftでNull判定をする10の方法

SwiftにおけるNull判定は、そのシンタックスの独自性から初心者にとってはやや難解に感じるかもしれません。

しかし、Swiftが提供するOptionalという仕組みを理解すれば、より安全で効果的なNull判定が実現できます。

ここでは、SwiftでのNull判定の具体的な手法を10の方法で解説します。

○サンプルコード1:基本的なNull判定

最も基本的なNull判定は、変数がnilかどうかをチェックすることです。

これは「==」演算子を使用して行います。

let string: String? = "Hello, Swift"
if string == nil {
    print("変数stringはnilです。")
} else {
    print("変数stringはnilではありません。")
}
// 出力結果は「変数stringはnilではありません。」となります。

このコードでは、Optional型の変数stringに値を代入し、その後==演算子でnilかどうかを判定しています。

○サンプルコード2:Optional Bindingを使った判定

SwiftではOptional Bindingという方法を使って、Optionalの値を安全に取り出すことができます。

「if let」というキーワードを使用します。

var optionalNumber: Int? = 100
if let actualNumber = optionalNumber {
    print("optionalNumberの値は\(actualNumber)です。")
} else {
    print("optionalNumberはnilです。")
}
// 出力結果は「optionalNumberの値は100です。」となります。

このコードでは、optionalNumberという変数に値が入っている場合、actualNumberという新しい変数にその値が代入され、その後の処理が実行されます。

もしoptionalNumberがnilの場合、elseのブロックが実行されます。

○サンプルコード3:Optional Chainingを利用した判定

Optional ChainingはSwiftの非常に便利な機能の一つです。

これを使用することで、複数のOptionalの連鎖的なアクセスが可能となり、中間の任意のステップでnilが返される場合、全体の式はすぐにnilとして評価されます。

例えば、クラスや構造体のプロパティやメソッドがOptionalである場合、Optional Chainingを使用して、そのプロパティやメソッドを安全にアクセスすることができます。

class Person {
    var residence: Residence?
}

class Residence {
    var numberOfRooms = 1
}

let john = Person()
// 初期値として、johnのresidenceはnil

if let roomCount = john.residence?.numberOfRooms {
    print("Johnの住居には\(roomCount)部屋があります。")
} else {
    print("Johnの住居情報は不明です。")
}
// 出力結果は「Johnの住居情報は不明です。」となります。

このコードでは、PersonというクラスがResidenceというクラスをOptionalのプロパティとして持っています。

そして、ResidencenumberOfRoomsというプロパティを持っています。

Optional Chainingを使用することで、john.residenceがnilでなければnumberOfRoomsにアクセスしようとします。

しかし、この例ではjohn.residenceはnilなので、全体の式もnilとして評価され、elseブロックが実行されます。

○サンプルコード4:Nil-Coalescing Operatorの使用例

Swiftには、Optionalがnilの場合にデフォルト値を返す、Nil-Coalescing Operatorという便利な演算子が存在します。

この演算子は??という記号で使用します。

let defaultColorName = "Red"
var userDefinedColorName: String?

let colorNameToUse = userDefinedColorName ?? defaultColorName
print(colorNameToUse)
// 出力結果は「Red」となります。

このコードでは、userDefinedColorNameというOptionalの変数が定義されていますが、初期値はnilです。

??を使用することで、userDefinedColorNameがnilの場合、defaultColorNameの値が代わりに使用されるようになります。

この方法を使用すると、Optionalの変数がnilかどうかに基づいて、簡単にデフォルト値を提供することができます。

○サンプルコード5:Guard文を活用したNull判定

Guard文はSwiftにおける強力な制御構造の一つです。

特に、Null判定やその他の条件判定において、コードの途中で特定の条件を満たしていることを保証したい場面でよく使用されます。

Guard文は、その条件が真でない場合、現在のスコープを即座に脱出します。

具体的な利用方法を見てみましょう。

func greet(_ person: [String: String]) {
    guard let name = person["name"] else {
        return
    }

    print("Hello, \(name)!")

    guard let age = person["age"] else {
        print("\(name)の年齢は不明です。")
        return
    }

    print("\(name)は\(age)歳です。")
}

let personInfo: [String: String] = ["name": "Taro"]
greet(personInfo)
// 出力結果
// Hello, Taro!
// Taroの年齢は不明です。

このコードでは、greetという関数が定義されており、辞書型の引数を取ります。

この関数内で、まずnameキーの値をGuard文を使用して取得し、次にageキーの値も同様に取得しています。

どちらかがnilの場合、Guard文は条件が満たされていないと判断し、現在のスコープを脱出します。

○サンプルコード6:If let文を使用した判定

SwiftにおけるNull判定の方法として、if let文も広く知られています。

この方法を使用することで、Optionalの値がnilでない場合に、その値を安全にアンラップして使用することができます。

実際の使用方法を確認しましょう。

var name: String? = "Yamada"
if let unwrappedName = name {
    print("名前は\(unwrappedName)です。")
} else {
    print("名前は不明です。")
}
// 出力結果
// 名前はYamadaです。

このコードでは、Optional String型の変数nameが定義されています。

if let文を使用することで、このnameがnilでない場合に、unwrappedNameという新しい変数にアンラップした値を代入し、その変数をスコープ内で使用しています。

この方法を使用すると、Optionalの変数を安全にアンラップして利用することができ、コードの可読性も向上します。

○サンプルコード7:Switch文でのNull判定

Switch文は、特定の値の状態に基づいて処理を切り替えるための強力な制御構造として知られています。

Swiftでは、Switch文を使用してOptionalの値がnilかnilでないかを判定することも可能です。

まず、Switch文を使ってNull判定を行う基本的なサンプルコードを見てみましょう。

var value: Int? = 10

switch value {
case .some(let actualValue):
    print("値は\(actualValue)です。")
case .none:
    print("値は存在しません。")
}
// 出力結果
// 値は10です。

このコードでは、Optional Int型の変数valueを定義し、Switch文を使用してその値がnilでない場合とnilの場合で異なるメッセージを表示しています。

.some(let actualValue)は、Optionalの値がnilでない場合にそのアンラップされた値をactualValueという変数に束縛します。

一方、.noneは、Optionalの値がnilの場合にマッチします。

次に、Switch文を使って複数のOptional変数のNull判定を同時に行うサンプルコードを紹介します。

var name: String? = "Taro"
var age: Int? = 20

switch (name, age) {
case let (.some(n), .some(a)):
    print("\(n)は\(a)歳です。")
case let (.some(n), .none):
    print("\(n)の年齢は不明です。")
case let (.none, .some(a)):
    print("名前は不明ですが、年齢は\(a)歳です。")
case (.none, .none):
    print("名前と年齢は両方とも不明です。")
}
// 出力結果
// Taroは20歳です。

このコードでは、2つのOptional変数nameageを同時にSwitch文で判定しています。

タプル(name, age)を使用することで、2つの変数の組み合わせごとに異なる処理を行うことができます。

Switch文を使用したNull判定は、複雑な条件や複数のOptional変数を扱う場合に特に役立ちます。

その柔軟性と明確な構文は、Swiftの魅力的な特徴の一つです。

この方法を適切に利用することで、コードの可読性を向上させることができます。

○サンプルコード8:Mapメソッドを使ったNull判定

SwiftのOptional型には、値がnilでない場合にその値を変換するためのmapメソッドが用意されています。

このメソッドを使用することで、Optionalの値を効果的に扱うことができます。

下記のサンプルコードでは、Optional Int型の変数valueを使用し、その値がnilでない場合に2倍に変換しています。

var value: Int? = 5
let doubledValue = value.map { $0 * 2 }
print(doubledValue) // Optional(10)

このコードを実行すると、アンラップせずにOptionalの値を2倍にした結果が表示されます。

mapメソッドは、値がnilである場合には何もせず、nilでない場合には指定した変換処理を行い、新しいOptionalの値を返します。

○サンプルコード9:FlatMapを活用した判定

Optional型の配列やコレクションを扱う際、flatMapメソッドは非常に有用です。

flatMapは、Optionalの値やコレクションを平坦化して、nilでない値のみを取り出すことができるメソッドとしてSwiftに実装されています。

たとえば、String型のOptionalの配列があり、それぞれのStringをIntに変換したい場合、flatMapを使うと簡単に実現できます。

変換できないStringはnilとなるため、そのような要素を自動的に除外したい場面でflatMapが役立ちます。

let stringNumbers: [String?] = ["1", "2", "3", "apple", nil, "5"]
let integers: [Int] = stringNumbers.flatMap { $0 }.compactMap { Int($0) }
print(integers) // [1, 2, 3, 5]

上のコードでは、Optional Stringの配列stringNumbersから、数字のStringのみを取り出し、それをIntに変換して新しい配列integersを作成しています。

まず、flatMapメソッドでnilを除外し、次にcompactMapメソッドでIntに変換できない要素を除外しています。

このように、flatMapを使うことで、複雑なデータ構造を持つ配列やコレクションをスムーズに扱うことができます。

特に、Optional型の配列を扱う際には、flatMapの活用は欠かせません。

○サンプルコード10:CompactMapを利用したNull判定

compactMapメソッドも、Optional型の配列やコレクションを扱う際に非常に役立つメソッドです。

このメソッドは、変換処理を行いつつ、変換後の値がnilの場合はその要素を除外する機能を持っています。

下記のサンプルコードでは、String型の配列をInt型の配列に変換する処理を表しています。

let stringValues = ["10", "20", "thirty", "40", "fifty"]
let integerValues: [Int] = stringValues.compactMap { Int($0) }
print(integerValues) // [10, 20, 40]

上のコードでは、String型の配列stringValuesから、Intに変換できるStringのみを取り出し、新しい配列integerValuesを作成しています。

変換できない要素、つまり”thirty”や”fifty”は自動的に除外されています。

●SwiftにおけるNull判定の応用例

SwiftでNull判定を学んだら、実際の開発現場やプロジェクトでの応用例を理解することが重要です。

ここでは、Null判定の技術を活用してデータベースの処理やAPIレスポンスの処理を行う方法を解説します。

○サンプルコード11:Null判定を活用したデータベースの処理

データベースから取得したデータは、しばしばOptional型で返ってきます。

これは、要求したデータがデータベースに存在しない場合や、何らかの理由で取得できなかった場合を考慮するためです。

下記のコードは、データベースからユーザー情報を取得し、そのユーザーの名前が存在する場合のみ表示しています。

struct User {
    var name: String?
    var age: Int?
}

// データベースから取得した想定のユーザーデータ
let retrievedUser: User? = User(name: "山田太郎", age: 25)

if let userName = retrievedUser?.name {
    print("ユーザー名:\(userName)")
} else {
    print("ユーザー名は存在しません。")
}

このコードを実行すると、ユーザー名が存在するため「ユーザー名:山田太郎」と表示されます。

○サンプルコード12:APIレスポンスのNull判定処理

外部APIからのレスポンスは、通信エラーやサーバーの問題、要求したデータが存在しない場合など、様々な理由で想定外の値やnilが返ってくることがあります。

そこで、Null判定を駆使して、安全にデータを扱う方法を学びましょう。

下記のコードは、APIからのレスポンスを模したJSONデータから、特定のキーの値を取得する例を表しています。

import Foundation

let jsonData = """
{
    "id": 12345,
    "name": "鈴木一郎",
    "email": null
}
""".data(using: .utf8)!

if let jsonObject = try? JSONSerialization.jsonObject(with: jsonData) as? [String: Any],
   let userName = jsonObject["name"] as? String {
    print("APIから取得したユーザー名:\(userName)")
} else {
    print("APIからユーザー名を取得できませんでした。")
}

このコードを実行すると、「APIから取得したユーザー名:鈴木一郎」と表示されます。

●Null判定の注意点と対処法

SwiftでNull判定を行う際、正確で安全なコードを書くために知っておくべきいくつかの注意点があります。

また、それらの注意点に対してどのように対処すれば良いかの方法も一緒に説明します。

○SwiftにおけるNullのトラブル事例

  1. Optional型の誤解:Optional型は、値が存在する場合と存在しない場合の2つの状態を持ちます。しかし、これを誤解して、nil以外の値が必ず存在すると考えてしまうと、ランタイムエラーが発生する可能性があります。
  2. force unwrappingの乱用:Optionalの値を取り出す際に、!を使用して強制的にアンラップすることは、nilの場合にクラッシュの原因となります。
  3. デフォルト値の不適切な使用:Nil-Coalescing Operatorを使用してデフォルト値を設定する場合、そのデフォルト値が適切でないと、誤った動作やバグの原因となることがあります。

下記のサンプルコードは、force unwrappingを乱用した場合の例を表しています。

var name: String? = nil
print(name!)  // クラッシュする

このコードでは、nameはnilのため、!を使用してアンラップするとアプリがクラッシュします。

○それらのトラブルを避けるための対処法

  1. Optional Bindingの利用:Optional Bindingを使用することで、値がnilでないことを確認した上で、値を取り出すことができます。
  2. Guard文の活用:関数やメソッドの冒頭でGuard文を使用することで、nilの場合の早期リターンを行い、その後のコードではOptionalでない値として安全に扱うことができます。
  3. デフォルト値の適切な設定:Nil-Coalescing Operatorを使用する際には、デフォルト値を適切に設定することで、意図しない動作やバグを防ぐことができます。

下記のサンプルコードは、Optional BindingとGuard文を利用して、安全にOptionalの値を取り出す方法を表しています。

var age: Int? = 25

if let unwrappedAge = age {
    print("年齢は\(unwrappedAge)歳です。")
} else {
    print("年齢は不明です。")
}

func displayAge(_ age: Int?) {
    guard let unwrappedAge = age else {
        print("年齢は不明です。")
        return
    }
    print("年齢は\(unwrappedAge)歳です。")
}

displayAge(age)

このコードを実行すると、2回とも「年齢は25歳です。」と表示されます。

●Null判定のカスタマイズ方法

Swiftの強力な言語仕様を活用することで、Null判定の方法をさらにカスタマイズして、プロジェクトの要件に合わせた判定方法を実装することが可能です。

○独自のNull判定関数の作り方

Swiftでは関数を自由に定義し、独自のNull判定方法を実装することができます。

例えば、特定の条件下でのみNilと判定したい場合や、特定の値をNilとして扱いたい場合など、様々なシチュエーションでカスタマイズされたNull判定が必要になるかと思います。

ここでは、Int型のOptional変数において、値が100以上の場合にはNilとして扱う独自のNull判定関数の一例を紹介します。

func customNullCheck(_ number: Int?) -> Bool {
    // nilの場合や100以上の場合はtrueを返す
    if let n = number, n < 100 {
        return false
    }
    return true
}

let sampleNumber1: Int? = 50
let sampleNumber2: Int? = 150
let sampleNumber3: Int? = nil

print(customNullCheck(sampleNumber1))  // false
print(customNullCheck(sampleNumber2))  // true
print(customNullCheck(sampleNumber3))  // true

このコードを実行すると、「false」「true」「true」という結果が得られます。

このように、独自の条件を追加することで、Null判定をより柔軟に行うことが可能です。

○外部ライブラリを活用した高度なNull判定

Swiftのコミュニティは非常に活発であり、多くのライブラリやフレームワークが提供されています。

Null判定をより効果的に行うための外部ライブラリも存在します。

これを利用することで、より高度なNull判定や独自の判定方法を取り入れることができます。

例として、「SwiftNullables」というライブラリを利用する方法を紹介します。

このライブラリは、Null判定を簡潔に行うための機能を提供しています。

まず、ライブラリのインストールを行います。

// Swift Package Managerを使用した場合のインストール方法
import PackageDescription

let package = Package(
    dependencies: [
        .package(url: "https://github.com/yourusername/SwiftNullables.git", from: "1.0.0")
    ]
)

次に、ライブラリを利用してNull判定を行うサンプルコードです。

import SwiftNullables

let value: Int? = nil
let result = value.isNull()  // trueが返される

このように、外部ライブラリを利用することで、標準の方法とは異なる、または標準の方法よりも簡潔なNull判定を実行することが可能です。

まとめ

SwiftでのNull判定は、プログラムの安全性や効率性を向上させるための不可欠なスキルです。

この記事を通して、SwiftにおけるNull判定の基本から高度な手法、さらにはカスタマイズ方法までを詳しく解説しました。

Swiftの特徴的な「Optional」はNull安全を保つための強力なツールであり、その利用方法や組み込みのNull判定機能を理解し、適切に活用することが重要です。

また、プロジェクトの要件や状況に応じて、独自のNull判定関数を作成したり、外部ライブラリを利用することで、更に柔軟かつ効果的なNull判定を実現することが可能です。

初心者の方から上級者の方まで、Swiftでのプログラミングを行う上でのNull判定の知識やスキルを深めることで、より堅牢でエラーに強いアプリケーションやシステムの開発が進められます。

日々のコーディングの中で、この記事の内容を思い出し、実践してみることをおすすめします。