Począwszy od Xcode 7 beta 5 (Swift Version 2) można teraz wydrukować nazwy typu i przypadki enum domyślnie przy użyciu print(_:)
, lub przekonwertować do String
korzystania String
„s init(_:)
składni inicjator lub ciąg interpolacji. Na przykład:
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"
Nie ma więc już potrzeby definiowania i utrzymywania wygodnej funkcji, która włącza każdy przypadek, aby zwrócić literał ciągu. Ponadto działa to automatycznie dla każdego wyliczenia, nawet jeśli nie określono typu wartości surowej.
debugPrint(_:)
& String(reflecting:)
może służyć do w pełni kwalifikowanej nazwy:
debugPrint(city)
// prints "App.City.Melbourne" (or similar, depending on the full scope)
let cityDebugName = String(reflecting: city)
// cityDebugName contains "App.City.Melbourne"
Pamiętaj, że możesz dostosować zawartość drukowaną w każdym z tych scenariuszy:
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)"
(Nie znalazłem sposobu, aby wywołać tę „domyślną” wartość, na przykład, aby wydrukować „Miasto to Melbourne” bez uciekania się do instrukcji przełącznika. Użycie \(self)
w implementacji description
/ debugDescription
powoduje nieskończoną rekurencję).
Powyższe komentarze String
„s init(_:)
& init(reflecting:)
inicjalizatorów opisać dokładnie co jest drukowane, w zależności od typu odbitych Przylega do:
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)
}
Zobacz informacje o wersji, aby uzyskać informacje o tej zmianie.
print(enum)
, możesz użyćString(enum)
CLAuthorizationStatus
wartość wyliczenia (celu C) wewnątrzlocationManager didChangeAuthorizationStatus
wywołania zwrotnego delegata, musisz zdefiniować rozszerzenie protokołu. Na przykład:extension CLAuthorizationStatus: CustomStringConvertable { public var description: String { switch self { case .AuthorizedAlways: return "AuthorizedAlways" <etc> } } }
- po wykonaniu tej czynności powinno działać zgodnie z oczekiwaniami: print ("Auth status: (\ status))".Obecnie nie ma introspekcji przypadków wyliczenia. Będziesz musiał zadeklarować je ręcznie:
Jeśli chcesz, aby typem surowym był Int, będziesz musiał samodzielnie dokonać zmiany:
źródło
get { ... }
część dla zwięzłości, jeśli nie zdefiniujesz ustawiacza.enum City : String, CustomStringConvertible {
. W ramach protokołu CSC będziesz musiał zmienić właściwość na publiczną , na przykład:public var description : String {
W Swift-3 (przetestowanym z Xcode 8.1) możesz dodać następujące metody w swoim wyliczeniu:
Następnie można go użyć jako normalnego wywołania metody w instancji wyliczenia. Może również działać w poprzednich wersjach Swift, ale nie testowałem tego.
W twoim przykładzie:
Jeśli chcesz zapewnić tę funkcjonalność wszystkim swoim wyliczeniom, możesz uczynić z niej rozszerzenie:
Działa to tylko w przypadku wyliczeń Swift.
źródło
W przypadku Objective-C
enum
wydaje się obecnie, że jedynym sposobem jest, na przykład, rozszerzenie wyliczenia,CustomStringConvertible
kończąc na czymś takim:A następnie rzucając
enum
jakoString
:źródło
String(describing:)
Inicjator może być używany do powrotu nazwę etykiety case nawet teksty stałe z rawValues non-string:Zauważ, że to nie zadziała, jeśli wyliczenie używa
@objc
modyfikatora:https://forums.swift.org/t/why-is-an-enum-returning-enumname-rather-than-caselabel-for-string-describing/27327
Generowane interfejsy Swift dla typów Objective-C czasami nie zawierają
@objc
modyfikatora. Te wyliczenia są jednak zdefiniowane w Objective-C, a zatem nie działają jak powyżej.źródło
Oprócz obsługi typu String (…) (CustomStringConvertible) dla wyliczeń w Swift 2.2 istnieje również nieco zepsuta obsługa odbić. W przypadku przypadków wyliczeniowych ze skojarzonymi wartościami można uzyskać etykietę przypadku wyliczenia przy użyciu odbicia:
Miałem jednak na myśli to, że dla „prostych” wyliczeń powyższa
label
obliczona właściwość oparta na odbiciu po prostu zwracanil
(boo-hoo).Najwyraźniej sytuacja z refleksją powinna się poprawić po Swift 3. Na razie rozwiązanie jest jednak
String(…)
, jak sugerowano w jednej z pozostałych odpowiedzi:źródło
var label:String { let mirror = Mirror(reflecting: self); if let label = mirror.children.first?.label { return label } else { return String(describing:self) } }
To jest takie rozczarowujące.
W przypadku, gdy potrzebujesz tych nazw (które kompilator doskonale zna dokładną pisownię, ale odmawia dostępu - dziękuję zespołowi Swift !! -), ale nie chcesz lub nie możesz uczynić z String bazy wyliczenia, a rozwlekła, uciążliwa alternatywa jest następująca:
Możesz użyć powyższego w następujący sposób:
Otrzymasz oczekiwany wynik (kod kolumny podobny, ale nie pokazany)
W powyższym odwołałem
description
właściwość dostring
metody, ale to kwestia gustu. Zwróć również uwagę, że tak zwanestatic
zmienne muszą być określane jako zakres przez nazwę ich otaczającego typu, ponieważ kompilator jest zbyt amnestyczny i nie może samodzielnie przypomnieć sobie kontekstu ...Zespół Swift naprawdę musi być dowodzony. Stworzyli enum, którego nie możesz,
enumerate
a na którym możesz użyćenumerate
„Sekwencji”, ale nieenum
!źródło
Natknąłem się na to pytanie i chciałem podzielić się prostym sposobem stworzenia wspomnianej funkcji magicFunction
źródło
Swift ma teraz tak zwaną niejawnie przypisaną wartość surową . Zasadniczo, jeśli nie podasz surowych wartości dla każdego przypadku, a wyliczenie jest typu String, wywnioskuje, że nieprzetworzona wartość przypadku jest sama w formacie ciągu. Dalej, spróbuj.
źródło
Dla Swift:
jeśli zmienna „batteryState”, wywołaj:
źródło
Proste, ale działa ...
źródło