enumStringEnum:String{case one ="one"case two ="two"case three ="three"}let anEnum =StringEnum(rawValue:"one")!
print("anEnum = \"\(anEnum.rawValue)\"")
Nota: No es necesario escribir = "uno", etc. después de cada caso. Los valores de cadena predeterminados son los mismos que los nombres de los casos, por lo que la llamada .rawValuesolo devolverá una cadena
EDITAR
Si necesita que el valor de la cadena contenga elementos como espacios que no son válidos como parte de un valor de caso, entonces debe establecer explícitamente la cadena. Entonces,
enumStringEnum:String{case one
case two
case three
}let anEnum =StringEnum.one
print("anEnum = \"\(anEnum)\"")
da
anEnum = "uno"
Pero si desea caseonemostrar el "valor uno", deberá proporcionar los valores de cadena:
enumStringEnum:String{case one ="value one"case two ="value two"case three ="value three"}
El valor bruto debe ser literalmente convertible. No puedes usar cualquier Hashabletipo.
Vatsal Manot
1
Ok ... Cité los documentos de Apple, que enumeran los tipos de valores que se pueden usar como valores sin procesar de enumeración. Las cadenas, la pregunta del OP, son uno de los tipos admitidos.
Duncan C
1
Hmm, imagina case one = "uno". Ahora, ¿cómo analizar el "one"valor de enumeración? (no se pueden usar raws, ya que se usan para la localización)
Agent_L
Tal vez podría inicializar la cadena sin procesar después de la inicialización dependiendo de la localización ... o simplemente tener una enumeración diferente cada una para una localización diferente. En cualquier caso, el propósito de tener una enumeración es abstraer el crudo subyacente, es decir, la localización. Un buen diseño de código no sería pasar "uno" como parámetro en ningún lugar, sino confiar en StringEnum.one
SkyWalker
5
No es necesario escribir, = "one"etc. después de cada caso. Los valores de cadena predeterminados son los mismos que los nombres de los casos.
emlai
38
Todo lo que necesitas es:
enumFoo:String{case a, b, c, d
}let a =Foo(rawValue:"a")
assert(a ==Foo.a)let 💩 =Foo(rawValue:"💩")
assert(💩 ==nil)
Esta no es técnicamente la respuesta correcta, ya que verifica el valor bruto. En el ejemplo que se muestra aquí, no se especifica ningún valor sin procesar, por lo que se corresponde implícitamente con el nombre del caso, pero si tiene una enumeración con un valor sin procesar, esto se rompe.
Mark A. Donohoe
26
En Swift 4.2, el protocolo CaseIterable se puede usar para una enumeración con rawValues, pero la cadena debe coincidir con las etiquetas de caso de enumeración:
enumMyCode:String,CaseIterable{case one ="uno"case two ="dos"case three ="tres"staticfunc withLabel(_ label:String)->MyCode?{returnself.allCases.first{"\($0)"== label }}}
¡Esta es una respuesta genial! De hecho, aborda la cuestión.
Matt Rundle
3
Esta es la única respuesta que realmente funciona como pidió el OP, que se refería a nombres de casos, no valores sin procesar. ¡Buena respuesta!
Mark A. Donohoe
1
Si bien esto funciona, es una tontería. No base la funcionalidad en nombres de casos en código.
Sulthan
7
¿Qué más se supone que debe hacer? ¿Qué pasa si está escribiendo una enumeración en una base de datos y luego necesita devolverla?
Joe
15
En caso de que tenga una enumeración con tipo Int, puede hacerlo así:
enumMenuItem:Int{caseOne=0,Two,Three,Four,Five//... as much as needs
staticfunc enumFromString(string:String)->MenuItem?{var i =0whilelet item =MenuItem(rawValue: i){ifString(item)== string {return item }
i +=1}returnnil}}
Y use:
let string ="Two"iflet item =MenuItem.enumFromString(string){//in this case item = 1
//your code
}
Es una locura que no pueda usar una funcionalidad similar incorporada en el lenguaje. Puedo imaginar que almacena valores en JSON, por ejemplo, por el nombre de enumeración, y luego, al analizar, debe convertirlos nuevamente. Escribir un enumFromStringmétodo para cada enumeración que usa parece una locura.
Peterdk
1
@Peterdk, sugiera la mejor alternativa posible. La solución de Igor realmente funcionó para mí.
Hemang
@Hemang Funciona bien, está bien, pero una mejor solución sería la compatibilidad con Swift para hacer esto automáticamente. Es una locura hacer esto manualmente para cada enumeración. Pero sí, esto funciona.
Peterdk
@Peterdk, ¿puede agregar una respuesta separada para lo mismo? Seguramente ayudaría a todos aquí.
Hemang
1
No es una locura que Swift no lo admita de forma nativa. Lo loco es que la funcionalidad se basa en el nombre de un tipo. Cuando el valor cambie, tendrá que refactorizar y renombrar todos los usos. Esta no es la forma correcta de solucionar este problema.
Respuestas:
Por supuesto. Las enumeraciones pueden tener un valor bruto. Para citar los documentos:
Entonces puedes usar un código como este:
Nota: No es necesario escribir = "uno", etc. después de cada caso. Los valores de cadena predeterminados son los mismos que los nombres de los casos, por lo que la llamada
.rawValue
solo devolverá una cadenaEDITAR
Si necesita que el valor de la cadena contenga elementos como espacios que no son válidos como parte de un valor de caso, entonces debe establecer explícitamente la cadena. Entonces,
da
Pero si desea
case
one
mostrar el "valor uno", deberá proporcionar los valores de cadena:fuente
Hashable
tipo.case one = "uno"
. Ahora, ¿cómo analizar el"one"
valor de enumeración? (no se pueden usar raws, ya que se usan para la localización)= "one"
etc. después de cada caso. Los valores de cadena predeterminados son los mismos que los nombres de los casos.Todo lo que necesitas es:
fuente
En Swift 4.2, el protocolo CaseIterable se puede usar para una enumeración con rawValues, pero la cadena debe coincidir con las etiquetas de caso de enumeración:
uso:
fuente
En caso de que tenga una enumeración con tipo Int, puede hacerlo así:
Y use:
fuente
enumFromString
método para cada enumeración que usa parece una locura.Ampliando la respuesta de Duncan C
fuente
Rápido 4.2:
fuente
Para Int enum y su representación de cadena, declaro enum de la siguiente manera:
Uso:
fuente