[Swift]カスタムrawタイプの列挙型


※この記事はSwift by Sundellの内容を日本語に翻訳したものです。

Swift列挙型はカスタムなRaw型をもてる

Swift列挙型は、Raw値(文字列や整数など)の完全なリストを作成するために非常に一般的に使用され、タイプセーフ(正しく型付けされたプログラムは不正な動作をしない)な方法で処理できます。たとえば、ファイル拡張子に基づいた形式のリストを含むVideoFormat列挙型を定義する方法は次のとおりです。

enum VideoFormat: String {
    case mp4
    case webM = "webm"
    case ogg
}

上記のようなRaw値ベースの列挙型を宣言すると、コンパイラは自動的にそれをRawRepresentableプロトコルに準拠させます。これにより、init?(rawValue :)イニシャライザやrawValueプロパティなどのAPIにアクセスできるようになります。列挙型のインスタンスとの間でRaw値を簡単に変換できるようにします。

この種の機能では、最初は列挙型のRawタイプStringのようなbuilt-in(組み込み)型にする必要があるように見えるかもしれませんが、実際には、両方がEquatableに準拠し、文字列または数値リテラルのいずれかを使用して表現される限り、完全にカスタムの型でも機能します。

例として、次のPath型を使用して、より強く型付けされた方法でファイルシステムパスをモデル化するアプリで作業しているとします(常にRaw文字列を渡すのと比較して)。

struct Path: Equatable {
    var string: String
}

PathベースのRaw値で列挙型を定義できたら、すばらしいと思いませんか?たとえば、次のように、特定のファイルシステム操作のターゲットの完全なリストを指定するには、次のようにします。

enum Target: Path {
    case content
    case resources
    case images = "resources/images"
}

すばらしいことに、上記を可能にするために必要なのは、Path型ExpressibleByStringLiteralに準拠させることだけです。残りはコンパイラーが処理します。

extension Path: ExpressibleByStringLiteral {
    init(stringLiteral: String) {
        string = stringLiteral
    }
}

列挙型が完全にカスタムのRaw型を持つことができるという事実は、Swiftのコア機能の多くが独自の型システムを使用して実装されていることのさらに別の例です。これにより、カスタム型が組み込み型とまったく同じように動作することが可能になります。

元の記事

Enums with custom raw types Swift by Sundell