ボクココ

個人開発に関するテックブログ

SwiftUI での オプショナル(Optional)型の対応

ども、@kimihom です。

f:id:cevid_cpp:20210814150213j:plain

ここ最近は Swift をいじっている。実装してみると、最初はこの Optional 型のコード意識の面倒さを感じていたが、慣れてくると便利だなと思えるようになってきた。

自分の認識をまとめる上でも、記事として記しておこう。

Optional 型の利用

まず、Swift では他の言語と同様に、Int, String などのような型定義がある。ただこれをそのまま使うには、最初から数字や文字列を入れておかないといけない。つまり nil を入れられない。

let year: int = 2021
let name: String = "kimihom"

基本的には上記にように 数字や文字列だけを入れるような実装となる。ただ、実際に iOS アプリを作ろうとすると、クラス内のオブジェクトを用意し、最初 nil定義することがよくある。

var appClient: HogeClient?

appClient = HogeClient.new
appClient.hello() // => エラー

上記エラーは、appClientnil の可能性がある状態のため、エラーとなる。以下のような選択肢がある。

1. if 文で埋め込む

if let client = appClient {
  client.hello()
}

2. ? Optional Chaining

appClient?.hello()

3. Guard 条件式

func someFunc() {
  guard let client = appClient else {
     print("appClient は nil")
     return
  }

  client.hello()
}

使い分け

感想だけど、上記3つ全部使いどきがある。 SwiftUI でコード書いているときに、どれ使うかの考えは基本的に以下だ。

1行だけで済む時: 2. ? Optional Chaining を使う。一行で全て済まされるコードのシンプルさが良い。

メソッド内で使う時: 3. Guard 条件式 を使う。1の if 文でも良いけども、guard の方が hello() メソッド実行時の タブを減らすことができる。また、if 文だと if {} else {} で囲った範囲でのみ利用となるので、 if の外では引き続き 使えない問題が起きる。 Guard ならそのメソッド内 guard より下のコードでは全て guard で定義した変数を使うことができる。余計なことを考えなくて済むのが guard のメリットだ。

上記 guard でのメソッドを if で書き換えるとこうなる。

func someFunc() {
  if let client = appClient { 
    client.hello()
  } else {
    print("appClient は nil")
  }

  // ここで `client` は使えない
}

client.hello() がタブ一つ奥で実行する必要があることがお分かりだろう。個人的に Optional型のためだけに タブが1つできてしまうのが全くもって気に入らない。ということで、実は 1. if 文で埋め込む は3つの中で最も使わないことが多い。

終わりに

とりあえず 「String? など ? 型定義した変数を使いたい時は、関数内で guard で新しい変数定義しておいて使う」というだけで、SwiftUI 開発は一気にスピードアップする気がしている。

さぁ、共に学んでいこう!

詳解 Swift 第5版

詳解 Swift 第5版

Amazon