enumStringEnum:String{case one ="one"case two ="two"case three ="three"}let anEnum =StringEnum(rawValue:"one")!
print("anEnum = \"\(anEnum.rawValue)\"")
Nota: Você não precisa escrever = "um" etc. após cada caso. Os valores de string padrão são iguais aos nomes de caso, então a chamada .rawValueirá retornar apenas uma string
EDITAR
Se você precisa que o valor da string contenha coisas como espaços que não são válidos como parte de um valor case, então você precisa definir explicitamente a string. Assim,
enumStringEnum:String{case one
case two
case three
}let anEnum =StringEnum.one
print("anEnum = \"\(anEnum)\"")
dá
anEnum = "um"
Mas se quiser caseoneexibir o "valor um", você precisará fornecer os valores da string:
enumStringEnum:String{case one ="value one"case two ="value two"case three ="value three"}
O valor bruto deve ser literalmente conversível. Você não pode usar qualquer Hashabletipo.
Vatsal Manot
1
Ok ... citei os documentos da Apple, que listam os tipos de valores que podem ser usados como valores brutos enum. Strings, a pergunta do OP, são um dos tipos suportados.
Duncan C
1
Hmm, imagine case one = "uno". Agora, como analisar "one"para valor enum? (não é possível usar raws, pois são usados para localização)
Agent_L
Talvez você possa inicializar a String bruta na inicialização, dependendo da localização ... ou simplesmente ter enum diferente cada para uma localização diferente. Em qualquer caso, todo o propósito de ter um enum é abstrair o bruto subjacente, ou seja, a localização. Um bom design de código não seria passar "uno" como parâmetro em qualquer lugar, mas confiar em StringEnum.one
SkyWalker
5
Você não precisa escrever = "one"etc. após cada caso. Os valores de string padrão são iguais aos nomes de caso.
emlai
37
Tudo o que você precisa é:
enumFoo:String{case a, b, c, d
}let a =Foo(rawValue:"a")
assert(a ==Foo.a)let 💩 =Foo(rawValue:"💩")
assert(💩 ==nil)
Esta não é tecnicamente a resposta certa, pois verifica o valor bruto. No exemplo aqui fornecido, não há valor bruto especificado, portanto, é implicitamente correspondido ao nome do caso, mas se você tiver um enum com um valor bruto, isso será interrompido.
Mark A. Donohoe
26
No Swift 4.2, o protocolo CaseIterable pode ser usado para um enum com rawValues, mas a string deve corresponder aos rótulos case enum:
enumMyCode:String,CaseIterable{case one ="uno"case two ="dos"case three ="tres"staticfunc withLabel(_ label:String)->MyCode?{returnself.allCases.first{"\($0)"== label }}}
Esta é uma ótima resposta! Na verdade, trata da questão.
Matt Rundle
3
Esta é a única resposta que realmente funciona como o OP pediu, que era sobre nomes de caso, não valores brutos. Boa resposta!
Mark A. Donohoe
1
Enquanto isso funciona, é uma coisa muito boba de se fazer. Não baseie a funcionalidade em nomes de casos no código.
Sulthan
7
O que mais ele deve fazer? E se ele estiver gravando um enum em um banco de dados e precisar convertê-lo de volta?
Joe
15
No caso de um enum com tipo Int, você pode fazer isso:
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}}
E use:
let string ="Two"iflet item =MenuItem.enumFromString(string){//in this case item = 1
//your code
}
É uma loucura que você não pode simplesmente usar uma funcionalidade semelhante embutida na linguagem. Posso imaginar que você armazene valores em JSON, por exemplo, pelo nome de enum e, em seguida, na análise, precise convertê-los de volta. Escrever um enumFromStringmétodo para cada enum que você usa parece loucura.
Peterdk
1
@Peterdk, por favor sugira a melhor alternativa possível. A solução Igor realmente funcionou para mim.
Hemang
@Hemang Funciona bem, certo, mas uma solução melhor seria o suporte do Swift para fazer isso automaticamente. É uma loucura fazer isso manualmente para cada enum. Mas sim, isso funciona.
Peterdk
@Peterdk, você poderia adicionar uma resposta separada para o mesmo? Certamente ajudaria a todos aqui.
Hemang
1
Não é loucura que o Swift não o suporte nativamente. A loucura é que a funcionalidade depende do nome de um tipo. Quando o valor mudar, você terá que refatorar e renomear todos os usos. Esta não é a maneira correta de resolver isso.
Respostas:
Certo. Enums podem ter um valor bruto. Para citar os documentos:
Portanto, você pode usar um código como este:
Nota: Você não precisa escrever = "um" etc. após cada caso. Os valores de string padrão são iguais aos nomes de caso, então a chamada
.rawValue
irá retornar apenas uma stringEDITAR
Se você precisa que o valor da string contenha coisas como espaços que não são válidos como parte de um valor case, então você precisa definir explicitamente a string. Assim,
dá
Mas se quiser
case
one
exibir o "valor um", você precisará fornecer os valores da string:fonte
Hashable
tipo.case one = "uno"
. Agora, como analisar"one"
para valor enum? (não é possível usar raws, pois são usados para localização)= "one"
etc. após cada caso. Os valores de string padrão são iguais aos nomes de caso.Tudo o que você precisa é:
fonte
No Swift 4.2, o protocolo CaseIterable pode ser usado para um enum com rawValues, mas a string deve corresponder aos rótulos case enum:
uso:
fonte
No caso de um enum com tipo Int, você pode fazer isso:
E use:
fonte
enumFromString
método para cada enum que você usa parece loucura.Ampliando a resposta de Duncan C
fonte
Swift 4.2:
fonte
Para Int enum e sua representação em String, declaro enum da seguinte forma:
Uso:
fonte