📘

if/switch式の恩恵(Swift5.9)

2023/08/01に公開

結論

Swift5.9からは#availableで次のような書き方ができて便利

let text = if #available(iOS 17, *) { "available!" } else { "unavailable" }

print("if-switch-expressions is", text) // "if-switch-expression is available!"

if/switch式

基本の書き方

サイコロの値によって結果を取得したいとき、今までは次のように書く必要がありました

// Swift5.9未満
let dice = Int.random(in: 1...100)

let simpleResult: String
if dice <= 50 {
  simpleResult = "成功"
} else {
  simpleResult = "失敗"
}

let completeResult: String
switch dice {
  case 1: "クリティカル"
  case 2...10: completeResult = "Extreme成功"
  case 11...25: completeResult = "Hard成功"
  case 25...50: completeResult = "成功"
  case 51...95: completeResult = "失敗"
  case 96...: completeResult = "ファンブル"
  default: completeResult = "失敗"
}

print(simpleResult) // "成功"
print(completeResult) // "クリティカル"

同じような処理を、swift5.9からは次のように書けるようになります

// Swift5.9以降
let dice = Int.random(in: 1...100)

let simpleResult = if dice <= 50 { "成功" } else { "失敗" }

let completeResult = switch dice {
  case 1: "クリティカル"
  case 2...10: "Extreme成功"
  case 11...25: "Hard成功"
  case 25...50: "成功"
  case 51...95: "失敗"
  case 96...: "ファンブル"
  default: "失敗"
}

print(simpleResult) // "成功"
print(completeResult) // "クリティカル"

少し簡潔に書けるようになって嬉しいですね

注意点

Swift5.9のif-switch-expressionsの書き方をする時にはいくつか注意点があり、主に覚えておくべきものを2つ紹介します
1. Must be a single expression
closureでreturnが省略できる場合と同じく、単一の式である必要があります
次のような場合もif-switch-expressionsは使えません。returnしてもダメです

let dice = Int.random(in: 1...100)
let result = if dice <= 50 {
  print("The dice roll has successed")
  "成功"
} else {
  print("The dice roll has failed")
  "失敗"
}

2. Must produce the same type
全ての分岐において、同じ型を返す必要があります
次のような場合がダメです。Xcodeもエラーを出してくれます

// エラー
let hoge = if .random() { 1.0 } else { 2 }

// 正しく同じ型
let hoge = if .random() { 1.0 } else { 2.0 }

ただし例外として、Errorをthrowする場合やfatalError()で止める場合は同じ型を返すという約束を守る必要はありません。

// 例外
let hoge = if .random() { 1.0 } else { fatalError() }

恩恵

本題
最初に結論として書きましたが、#availableが次のように書けるようにました!

let text = if #available(iOS 17, *) { "available!" } else { "unavailable" }

今まで↓

let text: String
if #available(iOS 17, *) {
  text = "available!"
} else { 
  text = "unavailable"
}

iOSバージョンの分岐が絡むと面倒なことにif文を単純に使う必要がありましたが、これでやっと三角演算子のように簡潔に書けます...

最後に

ここまで見ていただいてありがとうございました!
まだまだSwift/iOS勉強中の身ゆえ間違いや駄コード等あるかもしれません。もしそういったものを見かけたらぜひコメントで教えてください!こっそりと修正します

参考
swift-evolution

Discussion