web-dev-qa-db-fra.com

Dans Swift, est-il possible de convertir une chaîne en une énumération?

Si j'ai un enum avec les cas a, b, c, d est-il possible pour moi de lancer la chaîne "a" comme un enum?

77
user2763173

Sûr. Les enums peuvent avoir une valeur brute. Pour citer les docs:

Les valeurs brutes peuvent être des chaînes, des caractères ou n’importe quel type de nombre entier ou à virgule flottante

- Extrait de: Apple Inc. "Le langage de programmation Swift."). "IBooks. https://itun.es/us/jEUH0. l ,

Donc, vous pouvez utiliser un code comme ceci:

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

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

print("anEnum = \"\(anEnum.rawValue)\"")

Remarque: Vous n'avez pas besoin d'écrire = "un", etc. après chaque cas. Les valeurs de chaîne par défaut sont les mêmes que les noms de cas, appelant donc .rawValue retournera simplement une chaîne

MODIFIER

Si vous souhaitez que la valeur de chaîne contienne des éléments tels que des espaces non valides dans une valeur de cas, vous devez définir explicitement la chaîne. Alors,

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

let anEnum = StringEnum.one
print("anEnum = \"\(anEnum)\"")

donne

anEnum = "un"

Mais si vous voulez que caseone affiche "valeur un", vous devrez fournir les valeurs de chaîne:

enum StringEnum: String 
{
  case one   = "value one"
  case two   = "value two"
  case three = "value three"
}
114
Duncan C

Tout ce dont tu as besoin c'est:

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

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

let ???? = Foo(rawValue: "????")
assert(???? == nil)
24
emlai

Dans Swift 4.2, le protocole CaseIterable peut être utilisé pour une énumération avec rawValues, mais la chaîne doit correspondre aux libellés de la casse enum:

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)
16
djruss70

Dans le cas d'une énumération de type Int, vous pouvez le faire de la manière suivante:

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

Et utilise:

let string = "Two"
if let item = MenuItem.enumFromString(string) {
    //in this case item = 1 
    //your code
} 
14
Igor

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
    }
}
2
mr.boyfox

Étendre la réponse de Duncan C

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)
    }
}
1
gujci