Как получить строковое представление Swift enum по умолчанию для дальнейшей настройки
Начнем с перечисления в Swift:
enum UnitCode:UInt {
case Unknown = 0
case Hz = 1
case GPM = 2
case M3_Hour = 3
case mA = 4
case PSI = 5
case Bar = 6
}
Для большинства из них используется такое выражение:
let text = "\(aUnitCode)"
даст хороший результат, так как напечатанная форма соответствует форме кода (например, .Hz == "Hz").
Но для
M3_Hour
, Я хотел бы напечатать это как
m³/hr
. Так что соответствовать
CustomStringConvertable
, верно? Я подумал, что следующее не сработает:
extension UnitCode: CustomStringConvertible {
var description:String {
return self == .M3_Hour ? "m³/hr" : String(describing: self)
}
}
Это не так. Бесконечная рекурсия. Так и думал. Но Swift меня часто удивляет (как в хорошем, так и в плохом).
Если бы перечисление было отношением супер / подтип, я бы назвал «супер» версию описания, чтобы получить отображение текста перечисления «по умолчанию». Но я не уверен, как получить «строковую привязку перечисления по умолчанию» в моей ложной ветке, чтобы я мог настроить его только для одного отдельного значения. Есть ли способ сделать это?
3 ответа
Я думаю, проблема в том, что вы используете
String(describing:)
в реализации CustomStringConvertible. Если мы проигнорируем CustomStringConvertible и просто напишем настраиваемое свойство, вы сможете делать такие вещи:
enum UnitCode: UInt {
case Unknown = 0
case Hz = 1
case GPM = 2
case M3_Hour = 3
case mA = 4
case PSI = 5
case Bar = 6
var toString : String {
return self == .M3_Hour ? "m³/hr" : "\(self)"
}
}
Я не вижу для этого никакой рекурсии. (Однако я должен добавить, что считаю это хрупким; мы полагаемся на функцию, которая может не работать в будущем. Apple может изменить описание объекта в любое время.)
Комментарии о стиле и приемах приветствуются. Ответ, который я искал, пришел с форумов Swift и был очень простым:
К сожалению, нет. Функция, которую вам нужно вызвать, является внутренней по отношению к стандартной библиотеке.
Итак, в основном, механизм, который выполняет резервное преобразование из перечислений в их строки в кодировке, когда вы не предоставляете свои собственные
(Что @matt также сказал в комментариях, и если бы он дал такой ответ, я бы добавил еще больше очков к его огромному избытку репутации)
У меня это работает, надеюсь, вы этого и ожидали.
enum UnitCode: UInt {
case Unknown = 0
case Hz = 1
case GPM = 2
case M3_Hour = 3
case mA = 4
case PSI = 5
case Bar = 6
}
let anUnit: UnitCode = .M3_Hour
extension UnitCode: CustomStringConvertible {
var description: String {
switch self {
case .M3_Hour:
return "m³/hr"
default:
return String(describing: self)
}
}
}
print(anUnit.self)
//m³/hr