По состоянию на Xcode 7 беты 5 (Swift версия 2) теперь можно напечатать имена типов и случаи перечислений по умолчанию с использованием print(_:)
или обращенным в String
использовании String
«s 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"
Таким образом, больше нет необходимости определять и поддерживать вспомогательную функцию, которая включает каждый случай для возврата строкового литерала. Кроме того, это работает автоматически для любого перечисления, даже если тип необработанного значения не указан.
debugPrint(_:)
& String(reflecting:)
может использоваться для полного имени:
debugPrint(city)
// prints "App.City.Melbourne" (or similar, depending on the full scope)
let cityDebugName = String(reflecting: city)
// cityDebugName contains "App.City.Melbourne"
Обратите внимание, что вы можете настроить то, что напечатано в каждом из этих сценариев:
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)"
(Я не нашел способа вызвать это значение «по умолчанию», например, напечатать «Город - Мельбурн», не возвращаясь к инструкции switch. Использование \(self)
в реализации description
/ debugDescription
вызывает бесконечную рекурсию.)
Комментарии выше String
«S init(_:)
& init(reflecting:)
инициализаторах описывают именно то , что печатается, в зависимости от того , что отражено Соответствие нормам типа для:
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)
}
Смотрите информацию о выпуске для получения информации об этом изменении.
print(enum)
вы можете использоватьString(enum)
CLAuthorizationStatus
внутри вашегоlocationManager didChangeAuthorizationStatus
обратного вызова делегата, вам нужно определить расширение протокола. Например:extension CLAuthorizationStatus: CustomStringConvertable { public var description: String { switch self { case .AuthorizedAlways: return "AuthorizedAlways" <etc> } } }
- как только вы это сделаете, все должно работать так, как вы ожидаете: print ("Auth status: (\ status))".В настоящее время нет никакого самоанализа по случаям перечисления. Вы должны будете объявить их каждый вручную:
Если вам нужно, чтобы необработанный тип был Int, вам нужно будет переключиться самостоятельно:
источник
get { ... }
часть для краткости, если не определяете установщик.enum City : String, CustomStringConvertible {
. В качестве части протокола CSC вам потребуется изменить свойство на общедоступное , например:public var description : String {
В Swift-3 (протестировано с Xcode 8.1) вы можете добавить следующие методы в ваше перечисление:
Затем вы можете использовать его как обычный вызов метода для вашего экземпляра enum. Это может также работать в предыдущих версиях Swift, но я не проверял это.
В вашем примере:
Если вы хотите предоставить эту функциональность всем своим перечислениям, вы можете сделать это расширением:
Это работает только для перечислений Swift.
источник
Для Objective-C
enum
единственный способ, в настоящее время, кажется, например, состоит в том, чтобы расширить перечисление сCustomStringConvertible
помощью чего-то вроде:А потом применяете
enum
какString
:источник
String(describing:)
Инициализатор может быть использован , чтобы вернуть имя метки случая даже для перечислений с нестроковой rawValues:Обратите внимание, что это не работает, если перечисление использует
@objc
модификатор:https://forums.swift.org/t/why-is-an-enum-returning-enumname-rather-than-caselabel-for-string-describing/27327
Сгенерированные интерфейсы Swift для типов Objective C иногда не включают
@objc
модификатор. Эти перечисления, тем не менее, определены в Objective-C и, следовательно, не работают, как описано выше.источник
Помимо поддержки перечислений в Swift 2.2 для String (…) (CustomStringConvertible), для них также есть несколько неработающая поддержка отражений. Для случаев перечисления со связанными значениями можно получить метку случая перечисления, используя отражение:
Однако, будучи разбитым, я имел в виду, что для «простых» перечислений вышеуказанное
label
вычисленное свойство, основанное на отражении, просто возвращаетnil
(boo-hoo).Ситуация с отражением должна улучшиться после Swift 3, по-видимому. На данный момент решение
String(…)
, как предлагается в одном из других ответов:источник
var label:String { let mirror = Mirror(reflecting: self); if let label = mirror.children.first?.label { return label } else { return String(describing:self) } }
Это так разочаровывает.
Для случая, когда вам нужны эти имена (что компилятор прекрасно знает точное написание, но отказывается разрешить доступ - спасибо команде Swift !! -), но не хотите или не можете сделать String основой вашего перечисления, Подробная, громоздкая альтернатива выглядит следующим образом:
Вы можете использовать вышеизложенное следующим образом:
И вы получите ожидаемый результат (код для столбца похож, но не показан)
Выше я заставил
description
свойство возвращаться кstring
методу, но это дело вкуса. Также обратите внимание, что так называемыеstatic
переменные должны быть ограничены областью видимости по имени их включающего типа, так как компилятор слишком амнезичен и не может вызвать контекст сам по себе ...Команде Свифта действительно нужно командовать. Они создали перечисление, которое вы не можете
enumerate
и то, что вы можете использовать,enumerate
являются «последовательностями», но неenum
!источник
Я столкнулся с этим вопросом и хотел поделиться простым способом создания упомянутой волшебной функции.
источник
Swift теперь имеет то, что известно как неявно назначаемая необработанная стоимость . В основном, если вы не задаете необработанные значения для каждого случая, и перечисление имеет тип String, это выводит, что необработанное значение дела само является строковым форматом. Давай, попробуй.
источник
Для Свифта:
если ваша переменная "batteryState", то вызовите:
источник
Просто, но работает ...
источник
Кажется, самоанализ в Swift Enums работает частично.
Я видел ответ @ drewag и обнаружил, что Enum без rawValues действительно может иметь самоанализ в Swift 5.X с Xcode 11.5. Этот код работает.
Замените
"\(self)"
на"string"
секунду,Enum
и вы получите эту распечатку: сеть 404 строкиПРИМЕЧАНИЕ: Использование
String(self)
вместо"\(self)" in the first
Enumwill require the Enum to conform to the
LosslessStringConvertible` протокола, а также добавление других инициализаторов, поэтому интерполяция строк представляется хорошим обходным путем.Чтобы добавить a
var description: String
в перечисление, вы должны будете использовать оператор Switch во всех случаях перечисления, как указано ранееисточник