简体   繁体   中英

Get enum from property's raw value

Given the following enum:

enum Characters: String {

    case Joe, Frank, Jimmy

    var hairColor: String {
        switch self {
            case .Joe: return "Brown"
            case .Frank: return "Black"
            case .Jimmy: return "Blond"
        }
    }

    var style: String {
        switch self {
            case .Joe: return "Cool"
            case .Frank: return "Bad"
            case .Jimmy: return "Silent"
        }
    }
}

I'd like to be able to use rawValue to get the enum from the string of one of the properties. So, where I can do:

let newGuy = Characters(rawValue: "Joe")

and get .Joe , I also want to be able to do:

let newGuy = Characters(rawValue: "Cool")

and get .Joe


let newGuy = Characters.style(rawValue: "Cool")

does not work with an error of:

Instance member 'style' cannot be used on type 'Character'

Since style and hairColor are not related to the raw values you have to add appropriate initializers for example

 init?(style: String) {
    switch style {
    case "Cool": self = .Joe
    case "Bad": self = .Frank
    case "Silent": self = .Jimmy
    default: return nil
    }
 }

Why not the other way round ...

struct Person {

    enum HairColor {
        case brown, black, blond
    }

    enum Style {
        case cool, bad, silent
    }

    let name : String
    var hairColor : HairColor
    var style : Style
}

If you want to be able to create an enum based on an instance property value, you need to create your own initializer. With your current implementation, there is no mutual link between haircolor/style and the Character itself. The instance property (haircolor/style) is dependent on the Character, but the other way around there is no relation.

You have to create an initializer for both style and hairColor, I did it for style, you can do it for hairColor in a similar manner.

See the code below:

enum Characters: String {

    case Joe, Frank, Jimmy

    var hairColor: String {
        switch self {
        case .Joe: return "Brown"
        case .Frank: return "Black"
        case .Jimmy: return "Blond"
        }
    }

    var style: String {
        switch self {
        case .Joe: return "Cool"
        case .Frank: return "Bad"
        case .Jimmy: return "Silent"
        }
    }

    init(style: String){
        switch style {
        case "Cool":
            self = Characters.Joe
        case "Bad":
            self = Characters.Frank
        default:
            self = Characters.Jimmy
        }
    }
}

Characters(style: "Bad") //initializes Frank
Characters(rawValue: "Joe")  //works just like before

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM