在Swift中,是否可以将字符串转换为枚举?

82 enums swift

如果我有一个包含案例a,b,c的枚举,那么我是否可以将字符串"a"作为枚举?

Dun*_*n C 119

当然.枚举可以具有原始值.引用文档:

原始值可以是字符串,字符或任何整数或浮点数类型

- 摘自:Apple Inc."The Swift Programming Language."iBooks.https://itun.es/us/jEUH0.l ,

所以你可以使用这样的代码:

enum StringEnum: String 
{
  case one = "one"
  case two = "two"
  case three = "three"
}

let anEnum = StringEnum(rawValue: "one")!

print("anEnum = \"\(anEnum.rawValue)\"")
Run Code Online (Sandbox Code Playgroud)

注意:每个案例后你不需要写="一个"等.默认字符串值与案例名称相同,因此调用.rawValue只返回一个字符串

编辑

如果您需要字符串值来包含诸如作为案例值的一部分无效的空格之类的东西,那么您需要显式设置字符串.所以,

enum StringEnum: String 
{
  case one
  case two
  case three
}

let anEnum = StringEnum.one
print("anEnum = \"\(anEnum)\"")
Run Code Online (Sandbox Code Playgroud)

anEnum ="一"

但是如果要case one显示"value one",则需要提供字符串值:

enum StringEnum: String 
{
  case one   = "value one"
  case two   = "value two"
  case three = "value three"
}
Run Code Online (Sandbox Code Playgroud)

  • 在每个案例之后你不需要写一个"="一个"`等.默认字符串值与案例名称相同. (5认同)

eml*_*lai 31

所有你需要的是:

enum Foo: String {
   case a, b, c, d
}

let a = Foo(rawValue: "a")
assert(a == Foo.a)

let  = Foo(rawValue: "")
assert( == nil)
Run Code Online (Sandbox Code Playgroud)


djr*_*s70 17

在Swift 4.2中,CaseIterable协议可用于带有rawValues的枚举,但字符串应与枚举案例标签匹配:

enum MyCode : String, CaseIterable {

    case one   = "uno"
    case two   = "dos"
    case three = "tres"

    static func withLabel(_ label: String) -> MyCode? {
        return self.allCases.first{ "\($0)" == label }
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

print(MyCode.withLabel("one")) // Optional(MyCode.one)
print(MyCode(rawValue: "uno"))  // Optional(MyCode.one)
Run Code Online (Sandbox Code Playgroud)

  • 这是 OP 所要求的唯一实际有效的答案,它是关于 *case 名称 * 而不是原始值。好答案! (3认同)
  • 这是一个很好的答案!它实际上解决了这个问题。 (2认同)
  • 他还应该做什么?如果他正在将枚举写入数据库,然后需要将其抛回去怎么办? (2认同)

Igo*_*gor 15

对于具有Int类型的枚举,您可以这样做:

enum MenuItem: Int {
    case One = 0, Two, Three, Four, Five //... as much as needs

    static func enumFromString(string:String) -> MenuItem? {
        var i = 0
        while let item = MenuItem(rawValue: i) {
            if String(item) == string { return item }
            i += 1
        }
        return nil
    }
}
Run Code Online (Sandbox Code Playgroud)

并使用:

let string = "Two"
if let item = MenuItem.enumFromString(string) {
    //in this case item = 1 
    //your code
} 
Run Code Online (Sandbox Code Playgroud)

  • 您不能只使用语言中内置的类似功能,这太疯狂了。我可以想象您将值存储在 JSON 中,例如通过枚举名称,然后在解析时需要将它们转换回来。为您使用的每个枚举编写一个 `enumFromString` 方法似乎很疯狂。 (2认同)
  • Swift 本身不支持它并不奇怪。疯狂的是,该功能依赖于类型的名称。当值发生变化时,您将不得不重构和重命名所有用法。这不是解决此问题的正确方法。 (2认同)

aep*_*yus 9

借鉴 djruss70 的答案来创建高度通用的解决方案:

extension CaseIterable {
    static func from(string: String) -> Self? {
        return Self.allCases.first { string == "\($0)" }
    }
    func toString() -> String { "\(self)" }
}
Run Code Online (Sandbox Code Playgroud)

用法:

enum Chassis: CaseIterable {
    case pieridae, oovidae
}

let chassis: Chassis = Chassis.from(string: "oovidae")!
let string: String = chassis.toString()
Run Code Online (Sandbox Code Playgroud)

注意:不幸的是,如果枚举被声明为 @objc,这将不起作用。据我所知,从 Swift 5.3 开始,除了暴力解决方案(switch 语句)之外,没有办法让它与 @objc enum 一起工作。

如果有人碰巧知道一种方法可以使 @objc 枚举工作,我会对答案非常感兴趣。