protocol - rawValueを使用せずにenum内のString値にアクセスする



swift enum rawvalue to enum (3)

データベース内の列にアクセスするために使用しているキーのグローバル文字列定数を、入れ子になった列挙型に置き換えます。

構造は次のとおりです。

enum DatabaseKeys {

    enum User: String {
        case Table = "User"
        case Username = "username"
        ...
    }

    ...

}

データベース内の各テーブルは内部enumで、テーブルの名前はenumのタイトルです。 各列挙の最初のケースはテーブルの名前になり、次のケースはそのテーブルの列になります。

これを使うのはとても簡単です:

myUser[DatabaseKeys.User.Username.rawValue] = "Johnny"

しかし、私はこれらの列挙型を多用します。 すべてのインスタンスに.rawValueを追加し.rawValueばならないのは.rawValue.rawValueでいるほど読みやすいものではありません。 rawValueを使わずにString値にアクセスするにはどうすればよいですか? 私がこれを行うことができればそれは素晴らしいことだ:

myUser[DatabaseKeys.User.Username] = "Johnny"

私はSwift 2を使用していることに注意してください。これを達成するためのさらに良い方法があるなら、私はそれを聞きたいです!

https://src-bin.com


Answer #1

String代わりにUserを辞書のキーとして使うことができる場合( UserはデフォルトでHashableです)、それが解決策となります。

そうでない場合は、ネストした構造体と静的変数/定数を使用してください。


Answer #2

あなたはカスタムクラスでこれを行うことができます:

enum Names: String {
    case something, thing
}

class CustomData {
    subscript(key: Names) -> Any? {
        get {
            return self.customData[key.rawValue]
        }

        set(newValue) {
            self.customData[key.rawValue] = newValue
        }
    }

    private var customData = [String: Any]()
}

...

let cData = CustomData()
cData[Names.thing] = 56

編集する
私はSwift 3で動く別の解決策を見つけました:

enum CustomKey: String {
    case one, two, three
}

extension Dictionary where Key: ExpressibleByStringLiteral {
    subscript(key: CustomKey) -> Value? {
        get {
            return self[key.rawValue as! Key]
        }
        set {
            self[key.rawValue as! Key] = newValue
        }
    }
}

var dict: [String: Any] = [:]
dict[CustomKey.one] = 1
dict["two"] = true
dict[.three] = 3
print(dict["one"]!)
print(dict[CustomKey.two]!)
print(dict[.three]!)

Answer #3

列挙型で目的の構文を使用してこれを実行する方法が見つかりませんでしたが、これは構造体を使用して可能です。

struct DatabaseKeys {

    struct User {
        static let identifier = "User"
        static let Username = "username"
    }

}

使用するには:

myUser[DatabaseKeys.User.Username] = "Johnny"

Appleは、WatchKitテンプレートのストーリーボードと行タイプの識別子にこのような構造体を使います。





swift2