switchではなくて、if caseを使うサンプルコードをたまに目にします。
なんでだろう?と思ったので調べた際のメモを残しておきます。
指摘事項あればドシドシください!
結論
switchのほうが一般的に可読性は高いが、if caseのほうが簡潔にコードを記載できる場合があるから。
記事を漁ると上記の理由のために使っていると言う意見がチラホラありました。
なのでそう言うことなのだと思います。
検証1
言葉だけだと分かりづらいので、サンプルコードを試します。
以下の2つのサンプルコードだと、if caseもswitchも同じ結果になります。
let value = 1
if case 0 ..< 10 = value {
print("match")
} else {
print("not match")
}
// match
switch value {
case 0 ..< 10:
print("match")
default:
print("not match")
}
// match
enum Drink {
case Coffee
case Water
}
let drink = Drink.Coffee
if case .Coffee = drink {
print("coffee")
} else if case .Water = drink {
print("water")
}
switch drink {
case .Coffee:
print("coffee")
case .Water:
print("water")
}
// coffee
ん〜、switchのほうが読みやすい気がします。
しかし、switchのように常に分岐して判定しなければならないと言う場面ばかりではありません。
この条件のとき、これをしたいと言うときにswitchは重装です。
switchは仕様上、全てが網羅されるようにcaseを書かないといけません。
defaultも分岐先を作るためのcaseみたいなものですし。多分。
つまり、if case文であれば、else ifやelseを書かなくても、
この条件のとき、これをしたいと言う願いを簡潔に実装できると言う訳です。
以下、サンプルコードです。
let value = 1
if case 0 ..< 10 = value {
print("match")
}
// match
switch value {
case 0 ..< 10:
print("match")
default:
print("not match")
}
// match
enum Drink {
case Coffee
case Water
}
let drink = Drink.Coffee
if case .Coffee = drink {
print("coffee")
}
switch drink {
case .Coffee:
print("coffee")
case .Water:
print("water")
}
// coffee
上記サンプルコードだけだとあまりありがたみがないですが、
分岐が多い場合やシンプルに条件分岐したい時にありがたさを発揮するのが分かるかと思います。
余談1(guard caseもあるよ)
if caseだけでなく、guard caseってのもあります。
使い方は、if caseと一緒です。
サンプルコードです。
enum APIResponseType{
case Success(data: String, statusCode: Int)
case Error(data: String, statusCode: Int)
}
let result = APIResponseType.Success(data: "成功!!!", statusCode: 200)
if case .Success(let data, let statusCode) = result {
print("statusCode: \(statusCode)")
print("data: \(data)")
// 通信が成功した時の処理を記載
// ~~
}
enum APIResponseType{
case Success(data: String, statusCode: Int)
case Error(data: String, statusCode: Int)
}
let result = APIResponseType.Success(data: "成功!!!", statusCode: 200)
func test(){
guard case .Success(let data, let statusCode) = result else {
return
}
print("statusCode: \(statusCode)")
print("data: \(data)")
// 通信が成功した時の処理を記載
// ~~
}
test()
余談2(パターンマッチは ~= を使うこともあるよ)
パターンマッチは ~= を使うこともあります。
if caseのcaseを外して、= を ~= に変更するだけです。
let value = 1
if 0 ..< 10 ~= value {
print("match")
}
// match
enum Drink {
case Coffee
}
let drink = Drink.Coffee
if .Coffee ~= drink {
print("coffee")
}
// coffee
最後に
超基本的なことなんだろうし、モヤモヤがすっきりしたので良しとしよう!
同じような疑問の方の助けになっていたらなお良し!
本記事に対するコメントをいただいています。
実際に現場レベルで利用するときのことにも言及されているので、一読いただけると理解が深まると思います!
参考サイト
https://useyourloaf.com/blog/swift-if-case-let/
https://medium.com/swift-column/if-guard-case-529af6a50351
https://qiita.com/mono0926/items/f2875a9eacef53e88122#guard-case%E6%96%87
https://negichou.com/swift-enum-if-equatable/