Swiftの列挙型、switch文、網羅性チェックが素晴らしい!

公開日: : 最終更新日:2016/02/10 iOSアプリ開発

記事内に広告を含む場合があります。記事内で紹介する商品を購入することで、当サイトに売り上げの一部が還元されることがあります。

アップルの新プログラミング言語「Swift」をちょっとずついじってるんですが、列挙型とswitch文がなかなか便利になっていたので紹介したいと思います!

    

Objective-Cの列挙型

Objective-Cにおける列挙型の定義は、以下のように書きます。

typedef enum : NSUInteger {
    ColorTypeRed,
    ColorTypeGreen,
    ColorTypeBlue,
} ColorType;

    

例えば以下のように2つの列挙型を定義すると、BackgroundColorのRed, Green, Blueは二重定義ということで「Redefinition of enumerator ‘Red’」などのエラーが出てしまいます。

typedef enum : NSUInteger {
    Red,
    Green,
    Blue,
} TextColor;

typedef enum : NSUInteger {
    Red,
    Green,
    Blue,
} BackgroundColor;

    

これを回避するため、以下のように接頭辞を付けて名前が被らないようにする必要があります。

typedef enum : NSUInteger {
    TextColorRed,
    TextColorGreen,
    TextColorBlue,
} TextColor;

typedef enum : NSUInteger {
    BackgroundColorRed,
    BackgroundColorGreen,
    BackgroundColorBlue,
} BackgroundColor;

    

列挙型への代入は以下のように書きます。

ColorType color = ColorTypeBlue;

    

列挙型の値によってswitch文で分岐するには、以下のようなコードを書きます。

switch (color) {
    case ColorTypeRed:
        NSLog(@"赤");
        break;
    case ColorTypeGreen:
        NSLog(@"緑");
        break;
    case ColorTypeBlue:
        NSLog(@"青");
        break;
}

    

定義・代入・switch文などのすべてで接頭辞(ColorType…, TextColor…, BackgroundColor…)を何度も入力しなければならないので面倒くさいです。

    

Swiftの列挙型

Swiftにおける列挙型の定義は、以下のように書きます。

enum ColorType {
    case Red
    case Green
    case Blue
}

    

Swiftでは値の名前が被ったとしても接頭辞を付ける必要はありません。

enum TextColor {
    case Red
    case Green
    case Blue
}

enum BackgroundColor {
    case Red
    case Green
    case Blue
}

    

値を利用する際は、以下のように型名を先頭につけて区別します。

var color = ColorType.Blue
var textColor = TextColor.Blue
var backgroundColor = TextColor.Blue

    

変数の型名を明示的に指定する場合は、値の先頭に型名を付けなくても良いようです。

var color:ColorType = .Blue
var textColor:TextColor = .Blue
var backgroundColor:TextColor = .Blue

    

switch文のcaseでも、型名の指定は不要です。ちなみにSwiftのswitch文では、breakを付けなくてもbreakします。

switch color {
case .Red:
    NSLog("赤")
case .Green:
    NSLog("緑")
case .Blue:
    NSLog("青")
}

    

型名を接頭辞として付けなくても良くなったので、コードがシンプルで読みやすくなっていると感じます。

    

switch文の網羅性チェックが素晴らしい

Swiftのswitch文には「網羅性チェック」という機能が備わっており、これがなかなか素晴らしいです。

    

例えばObjective-Cで以下のようなコードを書いたとします。

typedef enum : NSUInteger {
    ColorTypeRed,
    ColorTypeGreen,
    ColorTypeBlue,
} ColorType;

switch (color) {
    case ColorTypeRed:
        NSLog(@"赤");
        break;
    case ColorTypeGreen:
        NSLog(@"緑");
        break;
    case ColorTypeBlue:
        NSLog(@"青");
        break;
}

    

その後、ColorTypeの値を以下のように増やしたとします。

typedef enum : NSUInteger {
    ColorTypeRed,
    ColorTypeGreen,
    ColorTypeBlue,
    ColorTypeYellow,
} ColorType;

    

ColorTypeYellow向けの処理をswitch文に追加し忘れた場合、プログラムが正しく動作しなくなる可能性があります。基本的にはコーディングする人間がこれをチェックしなければならないわけですが、人間はミスをするので安全とは言えません。

    

それに対してSwiftで同様のことを行ったとしましょう。

enum ColorType {
    case Red
    case Green
    case Blue
    case Yellow
}

switch color {
case .Red:
    NSLog("赤")
case .Green:
    NSLog("緑")
case .Blue:
    NSLog("青")
}

    

するとswitch文で以下のようなエラーが出ます。

Switch must be exhaustive, consider adding a default clause

    

このエラーを解決するには、.Yellowのcaseを追加するか、

switch color {
case .Red:
    NSLog("赤")
case .Green:
    NSLog("緑")
case .Blue:
    NSLog("青")
case .Yellow:
    NSLog("黄")
}

    

defaultを追加します。

switch color {
case .Red:
    NSLog("赤")
case .Green:
    NSLog("緑")
case .Blue:
    NSLog("青")
default:
    NSLog("その他の色")
}

    

つまり、Swiftのswitch文で列挙型を判定条件に使った場合、すべての値に対する処理が用意されているかを自動でチェックしてくれて、漏れがあればエラーで教えてくれるわけです。これにより、より安全なコードが書けそうです。

    

@akio0911はこう思った。

Swiftは「モダン、安全、高速、インタラクティブ」を大きな特徴として挙げていますが、今回紹介したswitch文の網羅性チェックはより安全なコードを書くための機能として追加されたのだと思います。

次に作るアプリはSwiftを使ってコードを書こうかなと思ってます!

この記事を書いた人
あきお(@akio0911
派手髪iOSエンジニア。Twitterアカウントは@akio0911。YouTubeチャンネル「あきおチャンネル」にてiOSアプリ開発講座を公開中。著書に「iPhoneアプリ開発レシピ」「cocos2d for iPhoneレッスンノート」など。iOSアプリ開発をテーマとしたオンラインサロン「アプリ道場サロン」を運営。東京・大阪にてアプリ開発講座「アプリクリエイター道場」を主催。

関連記事

この記事が気に入ったら「いいね!」しよう

Twitterで更新情報をゲット!

PAGE TOP ↑