Swift の if case / guard case によるパターンマッチングの使いどころ
今日したこんなツイートの補足ツイートをしようとしつつ、やや長くなりそうなので、プチ記事にしました( ´・‿・`)
上の例は、「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 case
や guard case
によるパターンマッチングを使っています。
switch animal2 {
case .🐶(let name):
print("イッヌ🐶(name: \(name))")
// switch文では基本的にはdefault使わずに全要素列挙した方が良いが、本当に🐶以外では何もしたくない今回のようなケースでは使って良さそう
default:
break
}
本記事で紹介した if case / guard case によるパターンマッチングは、以下にも載っています。
Swift 2のコードなので、3以降では調整必要なところがあると思いますが、パターンマッチ構文のバリエーション自体は当時からあまり増えていないので、今ざっと見るとのも有用だと思っています。