swift2 不使用rawValue访问枚举中的字符串值

twh00eeo  于 2022-11-06  发布在  Swift
关注(0)|答案(5)|浏览(183)

我想用一个嵌套的枚举来替换我的全局字符串常量,这个枚举是我用来访问数据库中的列的键。
其结构如下:

enum DatabaseKeys {

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

    ...

}

数据库中的每个表都是一个内部枚举,表的名称就是枚举的标题。每个枚举中的第一个case将是表的名称,下面的case是表中的列。
要使用它,非常简单:

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

但是我会经常使用这些枚举****。必须在每个示例后面追加.rawValue是一件痛苦的事情,而且它的可读性也不如我希望的那样好。我如何才能在不使用rawValue的情况下访问String值呢?如果我能做到这一点就太好了:

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

请注意,我使用的是Swift 2。如果有更好的方法来完成这一点,我很乐意听到它!

eoxn13cs

eoxn13cs1#

虽然我没有找到一种方法来使用所需的枚举语法来实现这一点,但使用结构体是可能的。

struct DatabaseKeys {

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

}

使用方法:

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

Apple在WatchKit模板中使用类似这样的结构体作为情节提要和行类型标识符。

68bkxrlz

68bkxrlz2#

您可以使用CustomStringConvertible通信协定来进行这项作业。
从文档中,
String(instance)适用于任何型别的执行严修,如果执行严修恰好是CustomStringConvertible,则会传回其描述。因此,不建议使用CustomStringConvertible做为泛型条件约束,或直接存取相容型别的描述。
因此,如果您遵循这个协议并通过description方法返回您的rawValue,您将能够使用String(Table.User)来获取该值。

enum User: String, CustomStringConvertible {

    case Table = "User"
    case Username = "username"

    var description: String {
        return self.rawValue
    }
}

var myUser = [String: String]()
myUser[String(DatabaseKeys.User.Username)] = "Johnny"

print(myUser) // ["username": "Johnny"]
okxuctiv

okxuctiv3#

您可以在符合String的枚举上使用callAsFunction(Swift 5.2中的新增功能)。

enum KeychainKey: String {
   case userId
   case email
}

func callAsFunction() -> String {
    return self.rawValue
}

使用方法:

KeychainKey.userId()
rpppsulh

rpppsulh4#

您可以使用自订类别来执行此作业:

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]!)
wlp8pajw

wlp8pajw5#

如果您能够使用User而不是StringUser默认为Hashable)作为字典关键字,这将是一个解决方案。
如果没有,您应该使用嵌套结构和静态变量/常量。

相关问题