Ab Xcode 7 Beta 5 (Swift Version 2) können Sie jetzt standardmäßig Typnamen und Aufzählungsfälle mit der Initialisierungs- oder Zeichenfolgeninterpolationssyntax drucken print(_:)
oder in diese konvertieren . Also für Ihr Beispiel:String
String
init(_:)
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"
Es ist also nicht mehr erforderlich, eine Komfortfunktion zu definieren und zu verwalten, die jeden Fall einschaltet, um ein Zeichenfolgenliteral zurückzugeben. Darüber hinaus funktioniert dies automatisch für jede Aufzählung, auch wenn kein Rohwerttyp angegeben ist.
debugPrint(_:)
& String(reflecting:)
kann für einen vollqualifizierten Namen verwendet werden:
debugPrint(city)
// prints "App.City.Melbourne" (or similar, depending on the full scope)
let cityDebugName = String(reflecting: city)
// cityDebugName contains "App.City.Melbourne"
Beachten Sie, dass Sie anpassen können, was in jedem dieser Szenarien gedruckt wird:
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)"
(Ich habe keine Möglichkeit gefunden, diesen "Standard" -Wert aufzurufen, um beispielsweise "Die Stadt ist Melbourne" zu drucken, ohne auf eine switch-Anweisung zurückzugreifen. Die Verwendung \(self)
bei der Implementierung von description
/ debugDescription
verursacht eine unendliche Rekursion.)
Die Kommentare über String
‚s init(_:)
& init(reflecting:)
initializers beschreiben genau das, was gedruckt wird, je nachdem , was die reflektierten Typ richtet sich:
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)
}
Siehe die Release Notes für Informationen zu dieser Änderung.
print(enum)
, können SieString(enum)
CLAuthorizationStatus
den Wert der Aufzählung (Ziel C) in IhremlocationManager didChangeAuthorizationStatus
Delegatenrückruf zu drucken , müssen Sie eine Protokollerweiterung definieren. Zum Beispiel:extension CLAuthorizationStatus: CustomStringConvertable { public var description: String { switch self { case .AuthorizedAlways: return "AuthorizedAlways" <etc> } } }
- Sobald Sie dies getan haben, sollte es wie erwartet funktionieren: print ("Auth status: (\ status))".Derzeit gibt es keine Selbstbeobachtung von Enum-Fällen. Sie müssen sie jeweils manuell deklarieren:
Wenn der Rohtyp ein Int sein soll, müssen Sie selbst einen Wechsel vornehmen:
quelle
get { ... }
Teil der Kürze halber auch weglassen, wenn Sie keinen Setter definieren.enum City : String, CustomStringConvertible {
. Als Teil des CSC-Protokolls müssen Sie dann die Eigenschaft ändern, um öffentlich zu sein , zum Beispiel:public var description : String {
In Swift-3 (getestet mit Xcode 8.1) können Sie die folgenden Methoden in Ihre Aufzählung aufnehmen:
Sie können es dann als normalen Methodenaufruf für Ihre Enum-Instanz verwenden. Es könnte auch in früheren Swift-Versionen funktionieren, aber ich habe es nicht getestet.
In Ihrem Beispiel:
Wenn Sie diese Funktionalität für alle Ihre Aufzählungen bereitstellen möchten, können Sie sie zu einer Erweiterung machen:
Dies funktioniert nur für Swift-Enums.
quelle
Für Objective-
enum
Cs scheint der einzige Weg derzeit beispielsweise darin zu bestehen, die Aufzählung so zu erweitern, dass am Ende FolgendesCustomStringConvertible
endet:Und dann das
enum
alsString
:quelle
Der
String(describing:)
Initialisierer kann verwendet werden, um den Namen der Fallbezeichnung auch für Aufzählungen mit Nicht-String-Rohwerten zurückzugeben:Beachten Sie, dass dies nicht funktioniert, wenn die Aufzählung den
@objc
Modifikator verwendet:https://forums.swift.org/t/why-is-an-enum-returning-enumname-rather-than-caselabel-for-string-describing/27327
Generierte Swift-Schnittstellen für Objective-C-Typen enthalten manchmal nicht den
@objc
Modifikator. Diese Aufzählungen sind dennoch in Ziel-C definiert und funktionieren daher nicht wie oben.quelle
Zusätzlich zur Unterstützung von String (…) (CustomStringConvertible) für Enums in Swift 2.2 gibt es auch eine etwas defekte Reflection-Unterstützung für diese. Für Enum-Fälle mit zugehörigen Werten ist es möglich, die Bezeichnung des Enum-Falls mithilfe von Reflection zu erhalten:
Mit "gebrochen" meinte ich jedoch, dass für "einfache" Aufzählungen die obige reflexionsbasierte
label
berechnete Eigenschaft nur zurückkehrtnil
(boo-hoo).Die Situation mit Reflexion sollte sich anscheinend nach Swift 3 verbessern. Die Lösung für den Moment ist jedoch
String(…)
, wie in einer der anderen Antworten vorgeschlagen:quelle
var label:String { let mirror = Mirror(reflecting: self); if let label = mirror.children.first?.label { return label } else { return String(describing:self) } }
Das ist so enttäuschend.
Für den Fall, dass Sie diese Namen benötigen (dass der Compiler die genaue Schreibweise genau kennt, aber den Zugriff verweigert - danke Swift-Team !! -), aber String nicht zur Basis Ihrer Aufzählung machen möchten oder können, a Die ausführliche, umständliche Alternative lautet wie folgt:
Sie können das Obige wie folgt verwenden:
Und Sie erhalten das erwartete Ergebnis (Code für die Spalte ähnlich, aber nicht angezeigt)
Oben habe ich die
description
Eigenschaft auf diestring
Methode zurückführen lassen , aber dies ist Geschmackssache. Beachten Sie auch, dass sogenanntestatic
Variablen durch den Namen ihres umschließenden Typs bereichsqualifiziert werden müssen, da der Compiler zu amnesisch ist und den Kontext nicht alleine aufrufen kann ...Das Swift-Team muss wirklich kommandiert werden. Sie haben eine Aufzählung erstellt, die Sie nicht können
enumerate
und für die Sieenumerate
"Sequenzen" verwenden können, aber nichtenum
!quelle
Ich bin auf diese Frage gestoßen und wollte einen einfachen Weg teilen, um die erwähnte magicFunction zu erstellen
quelle
Swift hat jetzt den sogenannten implizit zugewiesenen Rohwert . Wenn Sie nicht jedem Fall Rohwerte zuweisen und die Aufzählung vom Typ String ist, wird grundsätzlich abgeleitet, dass der Rohwert des Falls selbst im Zeichenfolgenformat vorliegt. Probieren Sie es weiter aus.
quelle
Für Swift:
Wenn Ihre Variable "Batteriezustand" lautet, rufen Sie auf:
quelle
Einfach aber funktioniert ...
quelle