如何从Swift的原始值中获取枚举?

Leo*_*Leo 61 enums ios swift

我正在尝试从原始值获取枚举类型:

enum TestEnum: String {
    case Name
    case Gender
    case Birth

    var rawValue: String {
        switch self {
        case .Name: return "Name"
        case .Gender: return "Gender"
        case .Birth: return "Birth Day"
        }
    }
}

let name = TestEnum(rawValue: "Name")       //Name
let gender = TestEnum(rawValue: "Gender")   //Gender
Run Code Online (Sandbox Code Playgroud)

但似乎这rawValue对带空格的字符串不起作用:

let birth = TestEnum(rawValue: "Birth Day") //nil
Run Code Online (Sandbox Code Playgroud)

任何建议如何获得它?

vad*_*ian 111

太复杂了,只需将原始值直接分配给案例

enum TestEnum: String {
  case Name = "Name"
  case Gender = "Gender"
  case Birth = "Birth Day"
}

let name = TestEnum(rawValue: "Name")!       //Name
let gender = TestEnum(rawValue: "Gender")!   //Gender
let birth = TestEnum(rawValue: "Birth Day")! //Birth
Run Code Online (Sandbox Code Playgroud)

如果案例名称与原始值匹配,您甚至可以省略它

enum TestEnum: String {
  case Name, Gender, Birth = "Birth Day"
}
Run Code Online (Sandbox Code Playgroud)

在Swift 3+中,所有enum案例都是 lowercased

  • 强制解包从其RawValue创建的枚举可能会导致运行时异常.最好使用"if let"构造来展开值.另请参阅:[Apple Enum Raw Value文档](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Enumerations.html#//apple_ref/doc/uid/TP40014097-CH12-ID149 ) (4认同)
  • 除了变量`name`等现在是Optionals,这可能不是OP想要的. (2认同)
  • 除了接收一个可选项之外没有别的办法(除非你想要一个字符串被传递时崩溃,这与枚举情况不对应). (2认同)

Str*_*ers 11

完整的工作示例:

enum TestEnum: String {
    case name = "A Name"
    case otherName
    case test = "Test"
}

let first: TestEnum? = TestEnum(rawValue: "A Name")
let second: TestEnum? = TestEnum(rawValue: "OtherName")
let third: TestEnum? = TestEnum(rawValue: "Test")

print("\(first), \(second), \(third)")
Run Code Online (Sandbox Code Playgroud)

所有这些都可行,但在使用原始值初始化时,它将是可选的.如果这是一个问题,你可以为枚举创建一个初始化器或构造函数来尝试处理它,添加一个nonecase并在无法创建枚举的情况下返回它.像这样的东西:

static func create(rawValue:String) -> TestEnum {
        if let testVal = TestEnum(rawValue: rawValue) {
            return testVal
        }
        else{
            return .none
        }
    }
Run Code Online (Sandbox Code Playgroud)


小智 6

使用Swift 4.2CaseIterable协议,它一点也不难!

这是一个如何实现它的示例。

import UIKit

private enum DataType: String, CaseIterable {
    case someDataOne = "an_awesome_string_one"
    case someDataTwo = "an_awesome_string_two"
    case someDataThree = "an_awesome_string_three"
    case someDataFour = "an_awesome_string_four"

    func localizedString() -> String {
        // Internal operation
        // I have a String extension which returns its localized version
        return self.rawValue.localized
    }

    static func fromLocalizedString(localizedString: String) -> DataType? {
        for type in DataType.allCases {
            if type.localizedString() == localizedString {
                return type
            }
        }
        return nil
    }

}

// USAGE EXAMPLE
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    if let dataType = DataType.fromLocalizedString(localizedString: self.title) {
        loadUserData(type: dataType)
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以轻松修改它以根据 rawValue 返回 DataType。我希望它有帮助!