Swift の if case / guard case によるパターンマッチングの使いどころ

mono 
Swift・iOSコラム
3 min readJun 26, 2017

今日したこんなツイートの補足ツイートをしようとしつつ、やや長くなりそうなので、プチ記事にしました( ´・‿・`)

aa

上の例は、「caseを使わずとも guard payload.aps.category == .dog else { return } と書けば良いのに」と思われそうで、確かにそう書ける時はそれがベターかなと思っています。

改めて書くと、次のような感じです。

enum Animal {
case
🐶,
🐱
}
let animal = Animal.🐶
if animal == .🐶 {
print("イッヌ🐶")
}

では、次のように associated valueをもつ列挙型の時はどうでしょうか?

enum Animal2 {
case
🐶(name: String),
🐱
}
let animal2 = Animal2.🐶(name: "mono")
if animal2 == .🐶 {
print("イッヌ🐶")
}

実行すると、次のエラーが発生してしまいます。

error: binary operator '==' cannot be applied to operands of type 'Animal2' and '_'
if animal2 == .🐶 {

そこで単純な == による比較の代わりに if case によるパターンマッチングの出番です。

if case .🐶 = animal2 {
print("イッヌ🐶")
}

こちらはコンパイルも無事通ります👏

もちろん、 name の値を受け取ることもできて(上のはそれを省略した書き方とも言えます)、次のように「イッヌ🐶(name: mono)」と出力することもできます。

if case .🐶(let name) = animal2 {
print("イッヌ🐶(name: \(name))")
}

素直に switch で書くと次のように少し長くなるので、それを簡潔に書きたいときにちょくちょく if caseguard case によるパターンマッチングを使っています。

switch animal2 {
case .🐶(let name):
print("イッヌ🐶(name: \(name))")
// switch文では基本的にはdefault使わずに全要素列挙した方が良いが、本当に🐶以外では何もしたくない今回のようなケースでは使って良さそう
default:
break
}

本記事で紹介した if case / guard case によるパターンマッチングは、以下にも載っています

Swift 2のコードなので、3以降では調整必要なところがあると思いますが、パターンマッチ構文のバリエーション自体は当時からあまり増えていないので、今ざっと見るとのも有用だと思っています。

--

--