In Swift, is it possible to convert a string to an enum?

后端 未结 8 952
[愿得一人]
[愿得一人] 2020-12-14 05:17

If I have an enum with the cases a,b,c,d is it possible for me to cast the string \"a\" as the enum?

相关标签:
8条回答
  • 2020-12-14 05:40

    Sure. Enums can have a raw value. To quote the docs:

    Raw values can be strings, characters, or any of the integer or floating-point number types

    — Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks. https://itun.es/us/jEUH0.l,

    So you can use code like this:

    enum StringEnum: String 
    {
      case one = "one"
      case two = "two"
      case three = "three"
    }
    
    let anEnum = StringEnum(rawValue: "one")!
    
    print("anEnum = \"\(anEnum.rawValue)\"")
    

    Note: You don't need to write = "one" etc. after each case. The default string values are the same as the case names so calling .rawValue will just return a string

    EDIT

    If you need the string value to contain things like spaces that are not valid as part of a case value then you need to explicitly set the string. So,

    enum StringEnum: String 
    {
      case one
      case two
      case three
    }
    
    let anEnum = StringEnum.one
    print("anEnum = \"\(anEnum)\"")
    

    gives

    anEnum = "one"

    But if you want case one to display "value one" you will need to provide the string values:

    enum StringEnum: String 
    {
      case one   = "value one"
      case two   = "value two"
      case three = "value three"
    }
    
    0 讨论(0)
  • 2020-12-14 05:46

    All you need is:

    enum Foo: String {
       case a, b, c, d
    }
    
    let a = Foo(rawValue: "a")
    assert(a == Foo.a)
    
    let                                                                     
    0 讨论(0)
  • 2020-12-14 05:46

    Swift 4.2:

    public enum PaymentPlatform: String, CaseIterable {
        case visa = "Visa card"
        case masterCard = "Master card"
        case cod = "Cod"
    
        var nameEnum: String {
            return Mirror(reflecting: self).children.first?.label ?? String(describing: self)
        }
    
        func byName(name: String) -> PaymentPlatform {
            return PaymentPlatform.allCases.first(where: {$0.nameEnum.elementsEqual(name)}) ?? .cod
        }
    }
    
    0 讨论(0)
  • 2020-12-14 05:46

    For Int enum and their String representation, I declare enum as follows:

    enum OrderState: Int16, CustomStringConvertible {
    
        case waiting = 1
        case inKitchen = 2
        case ready = 3
    
        var description: String {
            switch self {
            case .waiting:
                return "Waiting"
            case .inKitchen:
                return "InKitchen"
            case .ready:
                return "Ready"
            }
        }
    
        static func initialize(stringValue: String)-> OrderState? {
            switch stringValue {
            case OrderState.waiting.description:
                return OrderState.waiting
            case OrderState.inKitchen.description:
                return OrderState.inKitchen
            case OrderState.ready.description:
                return OrderState.ready
    
            default:
                return nil
            }
        }
    }
    

    Usage:

    order.orderState = OrderState.waiting.rawValue
    
    let orderState = OrderState.init(rawValue: order.orderState)
    let orderStateStr = orderState?.description ?? ""
    print("orderStateStr = \(orderStateStr)")
    
    0 讨论(0)
  • 2020-12-14 05:50

    Extending Duncan C's answer

    extension StringEnum: StringLiteralConvertible {
    
        init(stringLiteral value: String){
            self.init(rawValue: value)!
        }
    
        init(extendedGraphemeClusterLiteral value: String) {
            self.init(stringLiteral: value)
        }
    
        init(unicodeScalarLiteral value: String) {
            self.init(stringLiteral: value)
        }
    }
    
    0 讨论(0)
  • 2020-12-14 05:55

    In Swift 4.2, the CaseIterable protocol can be used for an enum with rawValues, but the string should match against the enum case labels:

    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 }
        }
    }
    

    usage:

    print(MyCode.withLabel("one")) // Optional(MyCode.one)
    print(MyCode(rawValue: "uno"))  // Optional(MyCode.one)
    
    0 讨论(0)
提交回复
热议问题