読者です 読者をやめる 読者になる 読者になる

学生かえるエンジニアのブログ

iOSを主にやる勉強中エンジニア。かえるが好き。ピクルスってかわいいよね。

Swiftで付属型enumを比較するとき

enumを比較する時、switchifを普通に使いますよね

大抵の場合はうまくいくんですが、付属型enum*1が含まれるとifでの比較がうまくいかなかったりします!

そんな時の書き方!

通常パターン

よく見る何もついてない普通のenumをswitchはうまくいく。

enum Mode {
    case special, normal, other
}
let mode: Mode = .special

// ビルド成功
switch mode {
case .special: break
default: break
}

// ビルド成功
if mode == .special {}

付属型enumパターン

次に1つだけ付属型enumにしてみましょう。

switchの比較では問題なくいきますが、if文ではエラーになります。

しかも、付属型にしたのはotherでありspecialは何もついていないのにビルドは通りません。

enum Mode {
    case special
    case normal
    case other(name: String)
}
let mode: Mode = .special

// ビルド成功
switch mode {
case .special: break
case .other: break
default: break
}

// エラー
if mode == .special {}

解決策

1. if文の書き方を工夫する

このように書きます。=は2つではなく1つです。

いっつもこの書き方を忘れるw

しかもこの書き方検索しても日本語記事が全然見つからない!

// 付属型enum を含む enum と比較する場合
if case Mode.special = mode {}
// 付属型の値を利用したい場合
if case let Mode.other(name) = mode {}

2. enumに関数を用意する (1.の書き方を忘れた場合)

1.での書き方を忘れたパターン。けどいちいちswitch文を書いてると行数が多くなり可読性が下がります。

そんな時はswitch比較をenum内で行いましょう。

enum Mode {
    case special
    case normal
    case other(name: String)
    
    // 関数を用意する
    func isSpecial() -> Bool {
        switch self {
        case .special:
            return true
        default:
            return false
        }
    }
    
    // get-only プロパティ版 (上記と同じ事)
    var isSpecial: Bool {
        switch self {
        case .special:
            return true
        default:
            return false
        }
    }
}

if mode.isSpecial {}

補足

switch文で付属の値を使用したい時は下記のように書きます。

switch mode {
case .other(let name):
    break
}

参考

Advanced & Practical Enum usage in Swift

後記

(Obj-Cから)swiftになりenumが便利になったとよく聞きます。try! Swift ではenumの話ばっかりだったとか。

それに加え自分の中ではswitch文もとても良くなったなと思っています。比較可能なものが増えインデントも同じになり、比較方法も色々かけ、、、

またこのブログでも分かる範囲でまとめていきたいなと思います。

間違い、追加情報等ありましたらコメントなど頂けますと幸いです。

try! Swift いきたいなぁ…

*1:関連型enum, Associated Value ともいう