Se ho un enum con i casi a, b, c, d è possibile per me lanciare la stringa "a" come enum?
Risposte:
Sicuro. Le enumerazioni possono avere un valore grezzo. Per citare i documenti:
I valori non elaborati possono essere stringhe, caratteri o qualsiasi tipo di numero intero o in virgola mobile
- Estratto da: Apple Inc. "The Swift Programming Language". iBooks. https://itun.es/us/jEUH0.l ,
Quindi puoi usare un codice come questo:
enum StringEnum: String
{
case one = "one"
case two = "two"
case three = "three"
}
let anEnum = StringEnum(rawValue: "one")!
print("anEnum = \"\(anEnum.rawValue)\"")
Nota: non è necessario scrivere = "uno" ecc. Dopo ogni caso. I valori di stringa predefiniti sono gli stessi dei nomi dei casi, quindi la chiamata .rawValue
restituirà solo una stringa
Se hai bisogno che il valore della stringa contenga cose come spazi che non sono validi come parte di un valore case, allora devi impostare esplicitamente la stringa. Così,
enum StringEnum: String
{
case one
case two
case three
}
let anEnum = StringEnum.one
print("anEnum = \"\(anEnum)\"")
dà
anEnum = "uno"
Ma se vuoi case
one
visualizzare il "valore uno" dovrai fornire i valori della stringa:
enum StringEnum: String
{
case one = "value one"
case two = "value two"
case three = "value three"
}
Hashable
tipo.
case one = "uno"
. Ora, come analizzare il "one"
valore enum? (non è possibile utilizzare raw, poiché vengono utilizzati per la localizzazione)
= "one"
ecc. Dopo ogni caso. I valori di stringa predefiniti sono gli stessi dei nomi dei casi.
Tutto ciò che serve è:
enum Foo: String {
case a, b, c, d
}
let a = Foo(rawValue: "a")
assert(a == Foo.a)
let 💩 = Foo(rawValue: "💩")
assert(💩 == nil)
In Swift 4.2, il protocollo CaseIterable può essere utilizzato per un'enumerazione con rawValues, ma la stringa deve corrispondere alle etichette enum case:
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 }
}
}
utilizzo:
print(MyCode.withLabel("one")) // Optional(MyCode.one)
print(MyCode(rawValue: "uno")) // Optional(MyCode.one)
Nel caso in cui con un enum con tipo Int puoi farlo così:
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
}
}
E usa:
let string = "Two"
if let item = MenuItem.enumFromString(string) {
//in this case item = 1
//your code
}
enumFromString
metodo per ogni enum che usi sembra folle.
Estendendo la risposta di 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)
}
}
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
}
}
Per Int enum e la loro rappresentazione String, dichiaro enum come segue:
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
}
}
}
Utilizzo:
order.orderState = OrderState.waiting.rawValue
let orderState = OrderState.init(rawValue: order.orderState)
let orderStateStr = orderState?.description ?? ""
print("orderStateStr = \(orderStateStr)")