J'essaie de me connecter à un enum:
enum CKAccountStatus : Int {
case CouldNotDetermine
case Available
case Restricted
case NoAccount
}
NSLog("%i", CKAccountStatus.Available)
Le compilateur se plaint:
Type 'CKAccountStatus' does not conform to protocol 'CVarArg'
Pourquoi? J'ai essayé de lancer la valeur:
NSLog("%i", CKAccountStatus.Available as Int)
Mais ça ne vole pas non plus:
Cannot convert the expression's type '()' to type 'String'
Obtenez la valeur Int
sous-jacente de l'énumération: CKAccountStatus.Available.rawValue
.
Les énumérations ne sont pas strictement des entiers dans Swift, mais si elles sont déclarées avec un type sous-jacent, vous pouvez l'obtenir avec rawValue
- quel que soit ce type sous-jacent. (enum Foo: String
vous donnera des chaînes pour la rawValue
, etc.) Si une énumération n'a pas de type sous-jacent, rawValue
n'a rien à vous donner. Dans les API importées d'ObjC, toute énumération définie avec NS_ENUM
a un type entier sous-jacent (généralement Int
).
Si vous souhaitez imprimer une énumération de manière plus descriptive, vous pouvez envisager de créer une extension sur le type d’énum qui adopte le protocole Printable
.
Une énumération est effectivement opaque. Il peut avoir des valeurs brutes, que vous pouvez obtenir; mais beaucoup d'énums ne le font pas. (Vous n'êtes pas obligé de déclarer l'énum comme ayant un type, et sinon, il n'y a pas de valeur brute.) Ce que je ferais, c'est de lui donner une méthode description
et de l'appeler explicitement.
Le seul moyen de distinguer la valeur actuelle de l'énum est d'utiliser une instruction switch. Votre méthode description
gérera chaque cas et chaque cas de l'instruction switch renverra une valeur descriptive différente.
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
Ceci est mon approche:
enum UserMode : String
{
case Hold = "Hold";
case Selecting = "Selecting";
case Dragging = "Dragging";
}
Ensuite, chaque fois que je dois imprimer la valeur brute:
//Assuming I have this declared and set somewhere
var currentMode: UserMode = .Selecting;
Faire
NSLog("CurrentMode \(_currMode.rawValue)");
Imprimera:
CurrentMode Sélection
De la documentation Swift:
Si vous connaissez C, vous saurez que les énumérations C attribuent des noms associés à un ensemble de valeurs entières. Les énumérations dans Swift sont beaucoup plus flexibles et n'ont pas à fournir de valeur pour chaque membre de l'énumération. Si une valeur (appelée valeur «brute») est fournie pour chaque membre d'énumération, elle peut être une chaîne, un caractère ou une valeur de type entier ou virgule flottante.
Par conséquent, vous ne pouvez pas essayer de le lancer vers et Int. En ce qui concerne votre premier problème, il semble que NSLog()
recherche un paramètre de type C-variable, qui ne s’applique pas à l’énumération Swift.
Pour mes énormes erreurs que j'utilise
public var localizedDescription : String { return String(reflecting: self) }
pour les autres énumérations, le protocole CustomStringConvertible peut être utilisé comme
public var description : String { return String(reflecting: self) }
Je vois, les énumérations ne sont pas des nombres dans Swift:
Contrairement à C et à Objective-C, les membres de l'énumération Swift ne sont pas affectés d'un valeur entière par défaut lors de leur création. Dans les CompassPoints exemple ci-dessus, Nord, Sud, Est et Ouest ne sont pas implicitement égaux à 0, 1, 2 et 3. Au lieu de cela, les différents membres du recensement sont des valeurs à part entière proprement dites, avec un .__ explicitement défini. type de CompassPoint.
Y at-il un moyen de consigner facilement la valeur, alors? Ah, il y a:
NSLog("%i", CKAccountStatus.Available.toRaw())
Vous pouvez utiliser la fonction toRaw()
pour obtenir la valeur int de l'énum comme suit:
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"