variable - Registro de una enumeración Swift utilizando NSLog
xcode print to debug console (7)
Estoy tratando de registrar una enumeración:
enum CKAccountStatus : Int {
case CouldNotDetermine
case Available
case Restricted
case NoAccount
}
NSLog("%i", CKAccountStatus.Available)
El compilador se queja:
Type ''CKAccountStatus'' does not conform to protocol ''CVarArg''
¿Por qué? He intentado lanzar el valor:
NSLog("%i", CKAccountStatus.Available as Int)
Pero eso tampoco vuela:
Cannot convert the expression''s type ''()'' to type ''String''
De los documentos Swift:
Si está familiarizado con C, sabrá que las enumeraciones de C asignan nombres relacionados a un conjunto de valores enteros. Las enumeraciones en Swift son mucho más flexibles y no tienen que proporcionar un valor para cada miembro de la enumeración. Si se proporciona un valor (conocido como valor "sin procesar") para cada miembro de la enumeración, el valor puede ser una cadena, un carácter o un valor de cualquier tipo de entero o punto flotante.
Por lo tanto, no puedes intentar lanzarlo hacia y Int. En cuanto a su primer problema, parece que NSLog()
está buscando un parámetro de tipo C-variable, que no se aplica a las enumeraciones de Swift.
Este es mi enfoque:
enum UserMode : String
{
case Hold = "Hold";
case Selecting = "Selecting";
case Dragging = "Dragging";
}
Luego, cuando necesito imprimir el valor bruto:
//Assuming I have this declared and set somewhere
var currentMode: UserMode = .Selecting;
Obra
NSLog("CurrentMode /(_currMode.rawValue)");
Se imprimirá:
Selección de modo actual
Obtenga el valor Int
subyacente de la enumeración: CKAccountStatus.Available.rawValue
.
Las enumeraciones no son estrictamente enteras en Swift, pero si se declaran con un tipo subyacente, se puede obtener con rawValue
, sea cual sea el tipo subyacente. ( enum Foo: String
le dará cadenas para el rawValue
, etc.) Si una enumeración no tiene un tipo subyacente, rawValue
no tiene nada que darle. En las API importadas de ObjC, cualquier enumeración definida con NS_ENUM
tiene un tipo entero subyacente (típicamente Int
).
Si desea imprimir cualquier enumeración de manera más descriptiva, podría considerar hacer una extensión en el tipo de enumeración que adopta el protocolo de impresión.
Para mi lista de errores utilizo
public var localizedDescription : String { return String(reflecting: self) }
para otras enumeraciones existe el protocolo CustomStringConvertible que se puede utilizar como
public var description : String { return String(reflecting: self) }
Puede usar la función toRaw()
para obtener el valor int de la enumeración como sigue:
import Foundation
enum CKAccountStatus : Int {
case CouldNotDetermine
case Available
case Restricted
case NoAccount
}
let block = {(status: Int) -> Void in
NSLog("%d", status)
}
let status = CKAccountStatus.Available.toRaw()
block(status) // prints "1"
Una enumeración es efectivamente opaca. Puede tener valores en bruto, que puede obtener; pero muchas enumeraciones no lo hacen. (No tiene que declarar que la enumeración tiene un tipo, y si no lo hace, no hay valores sin procesar). Lo que haría sería dar a la enumeración un método de description
y llamarlo explícitamente.
La única forma de distinguir el valor actual de la enumeración es a través de una declaración de cambio, de modo que su método de description
manejará cada caso, y cada caso de la instrucción de cambio devolverá un valor descriptivo diferente.
enum Suit {
case Hearts, Diamonds, Spades, Clubs
func description () -> String {
switch self {
case Hearts:
return "hearts"
case Diamonds:
return "diamonds"
case Spades:
return "spades"
case Clubs:
return "clubs"
}
}
}
var suit = Suit.Diamonds
println("suit /(suit.description())") // suit diamonds
Veo, las enumeraciones no son números en Swift:
A diferencia de C y Objective-C, a los miembros de la enumeración Swift no se les asigna un valor entero predeterminado cuando se crean. En el ejemplo anterior de CompassPoints, Norte, Sur, Este y Oeste no son iguales a 0, 1, 2 y 3. En su lugar, los diferentes miembros de la enumeración son valores completamente desarrollados por derecho propio, con un tipo de CompassPoint definido explícitamente.
¿Hay una manera de registrar fácilmente el valor, entonces? Ah, hay:
NSLog("%i", CKAccountStatus.Available.toRaw())