A partir de Xcode 7 beta 5 (Swift versión 2), ahora puede imprimir nombres de tipos y casos de enumeración de forma predeterminada utilizando print(_:)
, o String
usar String
la init(_:)
inicialización o la sintaxis de interpolación de cadenas. Entonces, para su ejemplo:
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"
Por lo tanto, ya no es necesario definir y mantener una función conveniente que active cada caso para devolver un literal de cadena. Además, esto funciona automáticamente para cualquier enumeración, incluso si no se especifica ningún tipo de valor sin procesar.
debugPrint(_:)
& String(reflecting:)
se puede usar para un nombre completo:
debugPrint(city)
// prints "App.City.Melbourne" (or similar, depending on the full scope)
let cityDebugName = String(reflecting: city)
// cityDebugName contains "App.City.Melbourne"
Tenga en cuenta que puede personalizar lo que se imprime en cada uno de estos escenarios:
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)"
(No he encontrado una manera de llamar a este valor "predeterminado", por ejemplo, para imprimir "La ciudad es Melbourne" sin recurrir a una declaración de cambio. El uso \(self)
en la implementación de description
/ debugDescription
provoca una recursión infinita).
Los comentarios anteriores String
's init(_:)
y init(reflecting:)
inicializadores describen exactamente lo que está impreso, dependiendo de qué tipo se ajusta a los reflejados a:
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 las notas de la versión para obtener información sobre este cambio.
print(enum)
, puede usarString(enum)
CLAuthorizationStatus
valor de la enumeración (Objetivo C) dentro de lalocationManager didChangeAuthorizationStatus
devolución de llamada de su delegado, deberá definir una extensión de protocolo. Por ejemplo:extension CLAuthorizationStatus: CustomStringConvertable { public var description: String { switch self { case .AuthorizedAlways: return "AuthorizedAlways" <etc> } } }
- una vez que haya hecho esto, debería funcionar como cabría esperar: print ("Estado de autenticación: (\ status))".No hay introspección en casos de enumeración en este momento. Deberá declararlos cada uno manualmente:
Si necesita que el tipo sin formato sea un Int, tendrá que hacer un cambio usted mismo:
fuente
get { ... }
parte por brevedad si no define un setter.enum City : String, CustomStringConvertible {
. Como parte del protocolo CSC, deberá cambiar la propiedad para que sea pública , por ejemplo:public var description : String {
En Swift-3 (probado con Xcode 8.1) puede agregar los siguientes métodos en su enumeración:
Luego puede usarlo como una llamada a método normal en su instancia de enumeración. También podría funcionar en versiones anteriores de Swift, pero no lo he probado.
En tu ejemplo:
Si desea proporcionar esta funcionalidad a todas sus enumeraciones, puede convertirla en una extensión:
Esto solo funciona para las enumeraciones Swift.
fuente
Para Objective-C
enum
, la única forma actualmente parece ser, por ejemplo, extender la enumeración paraCustomStringConvertible
terminar con algo como:Y luego lanzando el
enum
comoString
:fuente
El
String(describing:)
inicializador se puede usar para devolver el nombre de la etiqueta del caso incluso para enumeraciones con valores sin procesar de String:Tenga en cuenta que esto no funciona si la enumeración utiliza el
@objc
modificador:https://forums.swift.org/t/why-is-an-enum-returning-enumname-rather-than-caselabel-for-string-describing/27327
Las interfaces Swift generadas para los tipos Objective-C a veces no incluyen el
@objc
modificador. Sin embargo, esas enumeraciones se definen en Objective-C y, por lo tanto, no funcionan como anteriormente.fuente
Además del soporte de String (...) (CustomStringConvertible) para enumeraciones en Swift 2.2, también hay soporte de reflexión algo roto para ellos. Para casos enum con valores asociados, es posible obtener la etiqueta del caso enum mediante la reflexión:
Sin embargo, al estar roto, quise decir que para las enumeraciones "simples", la
label
propiedad calculada basada en la reflexión anterior simplemente devuelvenil
(boo-hoo).La situación con la reflexión debería estar mejorando después de Swift 3, aparentemente. Sin embargo
String(…)
, la solución por ahora es , como se sugiere en una de las otras respuestas:fuente
var label:String { let mirror = Mirror(reflecting: self); if let label = mirror.children.first?.label { return label } else { return String(describing:self) } }
Esto es muy decepcionante.
Para el caso en que necesita esos nombres (que el compilador conoce perfectamente la ortografía exacta, pero se niega a permitir el acceso, ¡gracias al equipo de Swift!), Pero no quiere o no puede hacer de String la base de su enumeración, un La alternativa detallada y engorrosa es la siguiente:
Puede usar lo anterior de la siguiente manera:
Y obtendrá el resultado esperado (código para la columna similar, pero no mostrado)
En lo anterior, hice que la
description
propiedad se refiera alstring
método, pero esto es cuestión de gustos. También tenga en cuenta que las llamadasstatic
variables deben ser calificadas por el alcance por el nombre de su tipo de inclusión, ya que el compilador es demasiado amnésico y no puede recordar el contexto por sí mismo ...El equipo Swift realmente debe ser comandado. ¡Crearon una enumeración que no puedes
enumerate
y que puedes usarenumerate
en "Secuencias" pero noenum
!fuente
Me topé con esta pregunta y quería compartir una forma simple de crear la función mágica mencionada
fuente
Swift ahora tiene lo que se conoce como valor bruto asignado implícitamente . Básicamente, si no proporciona valores sin formato a cada caso y la enumeración es de tipo String, deduce que el valor sin formato del caso está en formato de cadena. Vamos, dale una oportunidad.
fuente
Para Swift:
si su variable "batteryState" entonces llame:
fuente
Simple pero funciona ...
fuente