À partir de Xcode 7 beta 5 (Swift version 2), vous pouvez désormais imprimer les noms de type et les cas d'énumération par défaut en utilisant print(_:)
, ou convertir en String
utilisant String
l' init(_:)
initialiseur ou la syntaxe d'interpolation de chaîne. Donc pour votre exemple:
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"
Il n'est donc plus nécessaire de définir et de maintenir une fonction pratique qui active chaque cas pour renvoyer une chaîne littérale. De plus, cela fonctionne automatiquement pour toute énumération, même si aucun type de valeur brute n'est spécifié.
debugPrint(_:)
& String(reflecting:)
peut être utilisé pour un nom complet:
debugPrint(city)
// prints "App.City.Melbourne" (or similar, depending on the full scope)
let cityDebugName = String(reflecting: city)
// cityDebugName contains "App.City.Melbourne"
Notez que vous pouvez personnaliser ce qui est imprimé dans chacun de ces scénarios:
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)"
(Je n'ai pas trouvé de moyen d'appeler cette valeur "par défaut", par exemple, pour afficher "La ville est Melbourne" sans recourir à une instruction switch. L'utilisation \(self)
dans l'implémentation de description
/ debugDescription
provoque une récursivité infinie.)
Les commentaires ci - dessus String
de » init(_:)
& init(reflecting:)
initializers décrivent exactement ce qui est imprimé, en fonction de ce que répond le Type réfléchi à:
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)
}
Consultez les notes de version pour plus d'informations sur ce changement.
print(enum)
vous pouvez utiliserString(enum)
CLAuthorizationStatus
afficher la valeur de l'énumération (Objective C) dans votrelocationManager didChangeAuthorizationStatus
rappel de délégué, vous devez définir une extension de protocole. Par exemple:extension CLAuthorizationStatus: CustomStringConvertable { public var description: String { switch self { case .AuthorizedAlways: return "AuthorizedAlways" <etc> } } }
- une fois que vous avez fait cela, cela devrait fonctionner comme prévu: print ("Auth status: (\ status))".Il n'y a pas d'introspection sur les cas d'énumération pour le moment. Vous devrez les déclarer chacun manuellement:
Si vous avez besoin que le type brut soit un Int, vous devrez faire un changement vous-même:
la source
get { ... }
partie par souci de concision si vous ne définissez pas de setter.enum City : String, CustomStringConvertible {
. Dans le cadre du protocole CSC, vous devrez ensuite changer la propriété pour qu'elle soit publique , par exemple:public var description : String {
Dans Swift-3 (testé avec Xcode 8.1), vous pouvez ajouter les méthodes suivantes dans votre énumération:
Vous pouvez ensuite l'utiliser comme un appel de méthode normal sur votre instance enum. Cela pourrait également fonctionner dans les versions précédentes de Swift, mais je ne l'ai pas testé.
Dans votre exemple:
Si vous souhaitez fournir cette fonctionnalité à toutes vos énumérations, vous pouvez en faire une extension:
Cela ne fonctionne que pour les énumérations Swift.
la source
Pour les Objective-C,
enum
le seul moyen semble actuellement être, par exemple, d'étendre l'énumération enCustomStringConvertible
aboutissant à quelque chose comme:Et puis lancer le
enum
commeString
:la source
L'
String(describing:)
initialiseur peut être utilisé pour renvoyer le nom de l'étiquette de cas, même pour les énumérations avec des valeurs rawValues non String:Notez que cela ne fonctionne pas si l'énumération utilise le
@objc
modificateur:https://forums.swift.org/t/why-is-an-enum-returning-enumname-rather-than-caselabel-for-string-describing/27327
Les interfaces Swift générées pour les types Objective-C n'incluent parfois pas le
@objc
modificateur. Ces Enums sont néanmoins définis en Objective-C, et ne fonctionnent donc pas comme ci-dessus.la source
En plus du support String (…) (CustomStringConvertible) pour les énumérations dans Swift 2.2, il y a aussi un support de réflexion quelque peu cassé. Pour les cas d'énumération avec des valeurs associées, il est possible d'obtenir l'étiquette de cas d'énumération en utilisant la réflexion:
En étant cassé, je voulais dire que pour les énumérations "simples", la
label
propriété calculée basée sur la réflexion ci-dessus renvoie justenil
(boo-hoo).La situation avec réflexion devrait s'améliorer après Swift 3, apparemment. La solution pour l'instant est cependant
String(…)
, comme suggéré dans l'une des autres réponses:la source
var label:String { let mirror = Mirror(reflecting: self); if let label = mirror.children.first?.label { return label } else { return String(describing:self) } }
C'est tellement décevant.
Pour le cas où vous avez besoin de ces noms (dont le compilateur connaît parfaitement l'orthographe exacte, mais refuse de laisser l'accès - merci l'équipe Swift !! -) mais que vous ne voulez pas ou ne pouvez pas faire de String la base de votre énumération, un L'alternative verbeuse et lourde est la suivante:
Vous pouvez utiliser ce qui précède comme suit:
Et vous obtiendrez le résultat attendu (code pour la colonne similaire, mais non affiché)
Dans ce qui précède, j'ai fait
description
renvoyer la propriété à lastring
méthode, mais c'est une question de goût. Notez également que les soi-disantstatic
variables doivent être qualifiées de portée par le nom de leur type englobant, car le compilateur est trop amnésique et ne peut pas rappeler le contexte tout seul ...L'équipe Swift doit vraiment être commandée. Ils ont créé des énumérations que vous ne pouvez pas
enumerate
et que vous pouvez utiliserenumerate
sont des "séquences" mais pasenum
!la source
Je suis tombé sur cette question et je voulais partager un moyen simple de créer la magicFunction mentionnée
la source
Swift a maintenant ce que l'on appelle une valeur brute implicitement attribuée . Fondamentalement, si vous ne donnez pas de valeurs brutes à chaque cas et que l'énumération est de type String, cela en déduit que la valeur brute du cas est elle-même au format chaîne. Continuez à essayer.
la source
Pour Swift:
si votre variable "batteryState" alors appelez:
la source
Simple mais fonctionne ...
la source
L'introspection dans Swift Enums semble fonctionner partiellement.
J'ai vu la réponse de @ drewag et j'ai découvert qu'un Enum sans rawValues peut en effet avoir une introspection dans Swift 5.X avec Xcode 11.5. Ce code fonctionne.
Remplacez le
"\(self)"
for"string"
dans la secondeEnum
et vous obtiendrez cette impression: chaîne réseau 404REMARQUE: utiliser
String(self)
au lieu du protocole"\(self)" in the first
Enumwill require the Enum to conform to the
LosslessStringConvertible` et ajouter également d'autres initialiseurs, de sorte qu'une interpolation de chaîne semble être une bonne solution de contournement.Pour ajouter un
var description: String
à l'énumération, vous devrez utiliser une instruction Switch pour tous les cas d'énumération comme indiqué précédemmentla source