子枚举rawValue

时间:2019-06-16 11:59:30

标签: swift enums

考虑以下代码,我在其中声明了带有子枚举的enum

enum LocalizeKey {
case message(Messages)
case buttons(Buttons)
enum Buttons: String {
    case remove = "Remove"
    case add = "Add"
}
enum Messages: String {
    case success = "Success"
    case failure = "Failure"
 }
}

在没有子枚举的普通enum中,我们可以轻松访问.rawValue属性,并获取我们选择的任何大小写的原始值。

在这种情况下,我创建了一个类似这样的函数,只是要查看我得到了什么。

func keyString(for type: LocalizeKey) {
    print(type)
 }
keyString(for: .message(.failure)) // usage

问题:除.self之外,没有其他属性可以访问此LocalizeKey枚举。

我要实现的目标:也许您可以通过命名来关联,我正在尝试包装本地化的密钥,以便我可以根据密钥类型等轻松访问它们,并且{引用实际键的{1}}将进入rawValue函数。

游乐场输出:使用游乐场输出上方的功能是

  

消息(__lldb_expr_21.LocalizeKey.Messages.failure)

编辑:,而不必创建一个在每种情况下都会自动切换的变量,想象一下如果我们有+400键,那可能会很麻烦。

3 个答案:

答案 0 :(得分:1)

您需要在switch参数上type并进行模式匹配:

switch type {
    case .message(let messages): return messages.rawValue
    case .buttons(let buttons): return buttons.rawValue
}

您也可以将其扩展为LocalizeKey

extension LocalizeKey {
    var keyString: String {
        switch self {
            case .message(let messages): return messages.rawValue
            case .buttons(let buttons): return buttons.rawValue
        }
    }
}

答案 1 :(得分:1)

您将不得不切换到某个地方。如果只有少数“子枚举”,那么手动编写开关可能是最简单的:

func keyString(for type: LocalizeKey) {
  switch type {
  case .message(let message):
    print(message.rawValue)
  case .buttons(let button):
    print(button.rawValue)
  }
}

如果您不想手动编写此代码,则必须更改数据结构以便不需要它,或者使用code generation tool为您生成样板。

答案 2 :(得分:1)

尽管提到的答案确实提供了解决方案,但我还是提到了方法本身的问题:

在这一点上,必须在switch语句中添加每个新的大小写(关键字)以及相关的值,这似乎是不需要的样板代码;我假设您可以想象在枚举中包含许多情况时的样子。

因此,我建议采用一种更具动态性的方法,而不是在switch语句中手动添加每种情况的值。示例:

protocol Localizable {
    var value: String { get }
}

extension RawRepresentable where Self: Localizable, Self.RawValue == String {
    var value: String { return rawValue }
}

extension CustomStringConvertible where Self: RawRepresentable, Self.RawValue == String {
    var description: String { return rawValue }
}

struct LocalizeKey {

    enum Buttons: String, Localizable, CustomStringConvertible {
        case remove = "Remove"
        case add = "Add"
    }

    enum Messages: String, Localizable, CustomStringConvertible {
        case success = "Success"
        case failure = "Failure"
    }
}

我们正在为您的代码应用相同的逻辑,并进行了一些改进以使其易于维护。

基于此,您仍然可以将功能实现为:

func keyString(for type: Localizable) {
    print(type)
}

用法:

keyString(for: LocalizeKey.Buttons.add) // Add
keyString(for: LocalizeKey.Messages.success) // Success

IMO,我发现以这种方式进行调用似乎比拟议的方法(keyString(for: .message(.failure)))更易读,更直接。