【Swift】Optional型ラップアンラップまで完全理解!!

Swift

Optional型ってなかなかイメージしずらいですね。。。

学習していてあんまり掴めていなかったので、自分の理解促進も合わせてまとめてみました。

そもそもOptional型とは?

データ型の一つ。StringとかIntとかみたいなもの。

ただし、nilを代入することができる。(値が入っていることが確約されていない型)

このnilを代入できるは結構重要です。何故なら、このSwiftという言語は結構堅牢でnil(その他の言語ではnull)による弊害がないよう設計されています。

そのため、変数には基本的に何か値が入っていてアクセスした際に値がないってことがないのです。

つまり、Optional型は例外を許容している珍しい型なのです。

宣言方法

Optional型はString型のように直接値を代入して使うようなものではありません!

基本的に既存の方をOptional型に変換して使用します。

以下のコードを見てください。

var optionalVariable: Optional<String> = nil

上記のコードではOptional型で宣言していますが、<>で既存の方を包んでいるようになっています。

書式としては以下になります。

var(let) 変数名: Optional<型(String,Int,Double)>

ちなみにですが、もっと簡単に宣言する方法として以下の方法もあります。

var(let) 変数名: 型?

普通の型付きの変数宣言に「?」記号を付けることでOptional型の宣言ができます。

使い方はこんな感じです。

var exampleVariable: String? = nil

このように、簡単に記載ができることをプログラミングでは「シンタックスシュガー(糖衣構文)」と言います!!

ラップ

書籍などをているとラップするという単語をよく目にすると思います。

これは上記で説明した内容を踏まえれば理解できます!!!

既存の方をOptional型で包み込むことをラップというのです。

(ラップにはnilを許容する変数になることも意味します。)

アンラップ

アンラップとは、Optional型に変換した変数を元の型に戻すことです。

ラップとアンラップの関係は図に表すとこんな感じです。(イメージです)

Optional型に変換した変数を出力すると普通の変数を出力した時と比べると少し異なった表示になります。

以下を見てください。

// Optional型でラップする前
var optionalVariable: Optional<Int> = 1
print(optionalVariable)
// => Optional(1)

Optional(1)のようになってしまいます。

これは、Intではなく、Optionalでラップされているので出力内容もOptional型の出力になってしまっているためです。

Optional型になってしまったままでは不都合があります。

元の型に戻す方法が2通りあります。

1. 強制アンラップ

Optional型の変数を使う際にその変数の末尾に「!」を付ける方法です。

以下の例を見て下さい。

var optionalVariable: Optional<Int> = 1
print(optionalVariable!)
// => 1

Optional型で宣言して、出力する際にアンラップしてInt型の変数として出力させています。

このように、!を付けることで手軽に変数のアンラップが可能です。

ただし、これは変数の値が空でないことが必ず保証されている値で使わないと危険です。強制的に変換しているのでnilであった際には思わぬエラーにつながります。

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

なんか難しそうですが、そんなことはありません。

変数の中身を確認してnilかどうか確認してから取り出す方法です。

取り出し方には2通り方法があります。

ifを使う場合

ifを使って中身がnilかどうか確認してから値を取り出します。

以下のコードを見て下さい。

var optionalVariable: Optional<Int> = 1

if let unwrappedOptionalVariable = optionalVariable{
    print(unwrappedOptionalVariable)
}else{
    print("optionalVariabl is nil!!")
}
//=> 1

if文が使われていますが、ちょっと特殊ですよね。他の言語をつかているかたはなんか違和感がありますよね。(私は違和感バリバリでした。)

ifの後に、let〜で定数を宣言していますよね。これは、アンラップできるかどうか判定してnilでなければ定数に値を代入して{}内の処理を実行するということになります。

elseでは、アンラップできなかった時(nilであった時)の処理を記載します。

(letを使ってif内で宣言した変数はアンラップが失敗した際には使用することができません。)

ifを使ったアンラップの構文的は以下です。

if let 定数名 = アンラップするオプショナル型の変数{
    // オプショナル変数がnilで無かった時の処理
}else{
   // オプショナル変数がnilであった際の処理
}

guardを使う場合

guardを使って中身を確認してから処理をします。

以下のコードを見て下さい。

func unwarppedOptionalVariable(){
    var optionalVariable: Int? = 1
    
    guard let unwrappedOptionalVariable = optionalVariable else {
        print("optionalVariable is nil!!")
        return
    }
    print(unwrappedOptionalVariable)
}

unwarppedOptionalVariable()

// => 1

guardを使いnilの判定をしています。nilの場合には{}内の処理が実行されデバッグ分の出力とreturnが実行されることで関数を抜けます。

nilでない場合には、guard let 〜で宣言した変数に値が代入されguard以下の処理が実行されます。

guardを使ったアンラップ構文は以下になります。

guard let 定数名 = オプショナル型の変数 else {
        // オプショナル変数がnilだったときの処理
        return
    }
    // オプショナル変数がnil以外だったときの処理
}

終わり

オプショナル変数は、Swiftをやっていてつまづくポイントだと思います。

私も色々な文献を調べてなんとなく分かってきたので知識の整理も含めてまとめてみました。

誰かの役に立てれば幸いです。ではまたノシ

コメント

タイトルとURLをコピーしました