【2024年4月】弊社では、基本リモートワークで一緒に成長してくださるメンバーを広く募集させていただいております。 詳細はこちら

【Swift】コード内にある”はてな(?)”や”びっくりマーク(!)”(オプショナル型)の意味ついて理解する

【Swift】コード内にある"はてな(?)"や"びっくりマーク(!)"(オプショナル型)の意味ついて理解する
ふくしま

ドーナツの穴ぼこは存在か空白かという哲学にハッとしました。僕の答えは「美味しければなんでも良い」です。
こんにちは!メモリアインクのふくしまです。
今回は、swiftにおけるオプショナル型ついて見ていきましょう!

この記事を読んでわかること…
・オプショナル型とは何者か
・オプショナル型の宣言方法
・オプショナル型の値の取り出し方

目次

オプショナル型とは?

swiftにおけるオプショナル型は、変数が値を持つこともあれば、nil(値がないこと)を持つこともあることを示すための型です。
オプショナル型はSwiftの特徴的な機能で、より安全なコードを書くために役立ちます。

この記事では、オプショナル型の基本から応用までを説明します。

オプショナル型の宣言方法

オプショナル型の宣言

オプショナル型は型の後ろに をつけることで宣言します。

// ドーナツの穴("exist"(存在) or nil(空白))
var donutHole: String?

このコードは、donutHole (ドーナツの穴)はString (“存在する”)かもしれないし、nil かもしれないと宣言しています。

オプショナル型の値の代入

オプショナル型には値を代入することも、nilを代入することもできます。

donutHole = "存在"
donutHole = nil

オプショナル型の値の取り出しについて

値の取り出し????ってなりますよね。僕はなりました。
実はここがオプショナル型の真髄で、Swiftにおいて安全なプログラミングをサポートするための重要な機能といえます。

//ドーナツの穴("exist"(存在) or nil(空白))
var donutHole: String?

donutHole = "存在"
let myArgument = donutHole
print(myArgument)

先ほど宣言したオプショナル型の値donutHole に”存在する”を代入し、コンソールへ出力してみましょう。

出力結果:

Optional("存在")

何やら見慣れぬ文字が….。
このOptional("存在する") がオプショナル型で宣言した値の正体です。
冒頭でも説明したように、オプショナル型の値は、”値を持つこともあれば、持たないかもしれない”曖昧な状態です。
その曖昧な状態の値を開発者がしれっと使ってしまわないように、オプショナル型というシールドで守っているみたいなイメージです。

故に我々開発者側は、この曖昧な値に対して、状態を確定してやる(シールドを解く)必要があります。
この状態の確定のことを、アンラップと呼びます。

値の取り出しについて理解出来たところで、実際にオプショナル型から値を安全に取り出すいくつかの方法を見ていきましょう!

強制アンラップ

オプショナル型の値を取り出す最も単純な方法は、強制アンラップ(!)を使うことです。ただし、この方法はオプショナル型がnilでないことが確実な場合にのみ安全に使用できます。nilの場合、ランタイムエラーが発生します。

//ドーナツの穴("exist"(存在) or nil(空白))
var donutHole: String?

donutHole = "存在"
let myArgument = donutHole!
print(myArgument)

5行目のdonutHole! が該当箇所です。

出力結果:

存在

Optional("存在する") が消えて、値を正常に取り出すことが出来ていることを確認できました。

オプショナルバインディング

オプショナルバインディングを使うと、オプショナル型に値が存在する場合のみ、その値を一時的な定数または変数に代入して使用できます。

//ドーナツの穴("exist"(存在) or nil(空白))
var donutHole: String?

donutHole = "存在"
if var myArgument = donutHole {
    print("ドーナツの穴は\(myArgument)です。")
} else {
    print("ドーナツの穴は空白です。")
}

if文を使うことでnilの場合とそれ以外を明確化し、値を確定しています。

出力結果:

ドーナツの穴は存在です。

ガード文を使ったオプショナルバインディング

ガード文を使うと、早期リターンを行いながらオプショナル型をアンラップできます。
つまり、guard let でチェックした値がnilの場合、8行目の処理後11行目を処理せずにclame関数を抜けます。
これにより、ネストが深くなるのを防ぐことができます。

//ドーナツの穴("exist"(存在) or nil(空白))
var donutHole: String?

donutHole = "存在"
func clame() -> String {
    guard let myArgument = donutHole else {
            // optionalValueがnilの場合、ここで処理を終了します。
            return "私はドーナツの穴は空白だと思います。"
        }
        // この時点でvalueはアンラップされ、関数の残りの部分で利用できます。
        return "私はドーナツの穴は\(myArgument)だと思います。"
    }

print(clame())

出力結果:

私はドーナツの穴は存在だと思います。

if letguard let の使い分け
if letは特定の条件下でのみコードを実行したい場合に適しています。
guard letは、特定の条件が満たされない場合に早期に関数から抜け出すことを意図している場合に使用します。

nil合体演算子

nil合体演算子(??)を使うと、オプショナル型がnilの場合のデフォルト値を開発者側で設定できます。

//ドーナツの穴("exist"(存在する) or nil(存在しない))
var donutHole: String?

donutHole = nil
var myArgument = donutHole ?? "空白"

print("私の意見はドーナツの穴は\(myArgument)です")

5行目で、donutHole に値が入っている場合はその値を、nilの場合は??の後に定義した文字列(“空白”)を変数myArgument に格納します。

出力結果:

私の意見は空白です

まとめ

オプショナル型は、実際の開発シーンでもよく使われる重要な構文です。
DBでnil許容された値がnilで返ってきたにもかかわらず、受け取り側が強制アンラップしてしまっていたためアプリが落ちちゃうみたいなことは、よくやっちゃうミスなので、深く理解して使いこなせるようになっておきましょう!

ふくしま

この記事があなたのスキルアップに役立ったなら、次のキャリアステップを踏み出す絶好の機会かもしれません。エンジニアとしてのさらなる成長と挑戦を求めるなら、
未経験からIT・Webエンジニアを目指すなら【ユニゾンキャリア】
をオススメします!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

目次