A partir do Xcode 7 beta 5 (Swift versão 2) você pode agora imprimir nomes de tipo e casos de enumeração por padrão usando print(_:)
, ou converter para String
usar String
's init(_:)
sintaxe inicializador ou string de interpolação. Então, para o seu exemplo:
enum City: Int {
case Melbourne = 1, Chelyabinsk, Bursa
}
let city = City.Melbourne
print(city)
// prints "Melbourne"
let cityName = "\(city)" // or `let cityName = String(city)`
// cityName contains "Melbourne"
Portanto, não há mais a necessidade de definir e manter uma função de conveniência que alterne em cada caso para retornar uma string literal. Além disso, isso funciona automaticamente para qualquer enumeração, mesmo que nenhum tipo de valor bruto seja especificado.
debugPrint(_:)
& String(reflecting:)
pode ser usado para um nome completo:
debugPrint(city)
// prints "App.City.Melbourne" (or similar, depending on the full scope)
let cityDebugName = String(reflecting: city)
// cityDebugName contains "App.City.Melbourne"
Observe que você pode personalizar o que é impresso em cada um destes cenários:
extension City: CustomStringConvertible {
var description: String {
return "City \(rawValue)"
}
}
print(city)
// prints "City 1"
extension City: CustomDebugStringConvertible {
var debugDescription: String {
return "City (rawValue: \(rawValue))"
}
}
debugPrint(city)
// prints "City (rawValue: 1)"
(Não encontrei uma maneira de chamar esse valor "padrão", por exemplo, para imprimir "A cidade é Melbourne" sem recorrer a uma declaração de chave. \(self)
na implementação de description
/ debugDescription
causa uma recursão infinita.)
Os comentários acima String
são init(_:)
&init(reflecting:)
initializers descrever exatamente o que é impresso, dependendo do que o conforma tipo refletida para:
extension String {
/// Initialize `self` with the textual representation of `instance`.
///
/// * If `T` conforms to `Streamable`, the result is obtained by
/// calling `instance.writeTo(s)` on an empty string s.
/// * Otherwise, if `T` conforms to `CustomStringConvertible`, the
/// result is `instance`'s `description`
/// * Otherwise, if `T` conforms to `CustomDebugStringConvertible`,
/// the result is `instance`'s `debugDescription`
/// * Otherwise, an unspecified result is supplied automatically by
/// the Swift standard library.
///
/// - SeeAlso: `String.init<T>(reflecting: T)`
public init<T>(_ instance: T)
/// Initialize `self` with a detailed textual representation of
/// `subject`, suitable for debugging.
///
/// * If `T` conforms to `CustomDebugStringConvertible`, the result
/// is `subject`'s `debugDescription`.
///
/// * Otherwise, if `T` conforms to `CustomStringConvertible`, the result
/// is `subject`'s `description`.
///
/// * Otherwise, if `T` conforms to `Streamable`, the result is
/// obtained by calling `subject.writeTo(s)` on an empty string s.
///
/// * Otherwise, an unspecified result is supplied automatically by
/// the Swift standard library.
///
/// - SeeAlso: `String.init<T>(T)`
public init<T>(reflecting subject: T)
}
Consulte as notas de versão para obter informações sobre essa alteração.
print(enum)
você pode usarString(enum)
CLAuthorizationStatus
valor da enumeração (Objective C) dentro dolocationManager didChangeAuthorizationStatus
retorno de chamada do seu representante, precisará definir uma extensão de protocolo. Por exemplo:extension CLAuthorizationStatus: CustomStringConvertable { public var description: String { switch self { case .AuthorizedAlways: return "AuthorizedAlways" <etc> } } }
- depois de fazer isso, deve funcionar como esperado: print ("Status de autenticação: (\ status))".Não há introspecção em casos de enum no momento. Você precisará declará-los manualmente:
Se você precisar que o tipo bruto seja um Int, precisará fazer uma alternância:
fonte
get { ... }
peça por questões de brevidade se não definir um setter.enum City : String, CustomStringConvertible {
. Como parte do protocolo CSC, você precisará alterar a propriedade para ser pública , por exemplo:public var description : String {
No Swift-3 (testado com o Xcode 8.1), você pode adicionar os seguintes métodos na sua enumeração:
Você pode usá-lo como uma chamada de método normal em sua instância de enum. Também pode funcionar nas versões Swift anteriores, mas não testei.
No seu exemplo:
Se você deseja fornecer essa funcionalidade a todas as suas enumerações, é possível torná-la uma extensão:
Isso funciona apenas para enumerações Swift.
fonte
Para Objective-C
enum
s, atualmente, a única maneira atualmente parece ser, por exemplo, estender o enum eCustomStringConvertible
terminar com algo como:E, em seguida, lançando o
enum
comoString
:fonte
O
String(describing:)
inicializador pode ser usado para retornar o nome do rótulo do caso, mesmo para enumerações com RawValues não String.Observe que isso não funciona se o enum usa o
@objc
modificador:https://forums.swift.org/t/why-is-an-enum-returning-enumname-rather-than-caselabel-for-string-describing/27327
As interfaces Swift geradas para tipos de Objective-C às vezes não incluem o
@objc
modificador. No entanto, esses Enums são definidos no Objective-C e, portanto, não funcionam como acima.fonte
Além do suporte a String (…) (CustomStringConvertible) para enumerações no Swift 2.2, também há um suporte de reflexão um pouco quebrado para elas. Para casos enum com valores associados, é possível obter o rótulo do caso enum usando reflexão:
Por estar quebrado, no entanto, quis dizer que, para enums "simples", a
label
propriedade computada baseada em reflexão acima retornanil
(boo-hoo).A situação com a reflexão deve melhorar depois de Swift 3, aparentemente. A solução por enquanto é
String(…)
, como sugerido em uma das outras respostas:fonte
var label:String { let mirror = Mirror(reflecting: self); if let label = mirror.children.first?.label { return label } else { return String(describing:self) } }
Isso é tão decepcionante.
Para o caso em que você precisa desses nomes (que o compilador conhece perfeitamente a ortografia exata, mas se recusa a permitir o acesso - obrigado equipe Swift !! -), mas não deseja ou não pode fazer de String a base de sua enumeração, alternativa detalhada e complicada é a seguinte:
Você pode usar o acima, da seguinte maneira:
E você obterá o resultado esperado (código da coluna semelhante, mas não mostrado)
No exposto, fiz a
description
propriedade se referir novamente aostring
método, mas isso é uma questão de gosto. Observe também que os chamadosstatic
variáveis precisam ser qualificadas pelo escopo pelo nome de seu tipo de anexo, pois o compilador é muito amnésico e não pode recuperar o contexto por si só ...A equipe Swift deve realmente ser comandada. Eles criaram um enum que você não pode
enumerate
e o que pode usarenumerate
são "Sequências", mas nãoenum
!fonte
Eu me deparei com essa pergunta e queria compartilhar uma maneira simples de criar a função mágica mencionada
fonte
Agora, o Swift tem o que é conhecido como Valor Bruto Atribuído Implicitamente . Basicamente, se você não fornecer valores brutos para cada caso e a enumeração for do tipo String, deduzirá que o valor bruto do caso está no formato de string. Vá em frente, tente.
fonte
Para Swift:
se sua variável "batteryState", ligue para:
fonte
Simples, mas funciona ...
fonte