Создание пользовательского стиля формата для всех единиц измерения.
У меня есть несколько измерений (например,UnitLength
, ,UnitSpeed
и т. д.), и для большинства из них я хочу иметь форматтер, который использует предоставленный модуль (formatter.unitOptions = .providedUnit
).
Чтобы упростить сайт вызова, я создал собственный FormatStyle — по длине он выглядит так:
struct ProvidedUnitFormatStyle: FormatStyle {
func format(_ measurement: Measurement<UnitLength>) -> String {
let formatter = MeasurementFormatter()
formatter.unitOptions = .providedUnit
return formatter.string(from: measurement)
}
}
extension FormatStyle where Self == ProvidedUnitFormatStyle {
static var providedUnit: ProvidedUnitFormatStyle { .init() }
}
// usage: distance.formatted(.providedUnit)
Но если я хочу сделать то же самое дляUnitDuration
, мне придется повторить этот код.
Я попробовал использовать вfunc format()
, надеясь, что смогу использовать это для всех модулей, но компилятор жалуется:
Метод экземпляра «форматированный» требует типов
Measurement<Dimension>
иMeasurement<UnitDuration>
быть эквивалентным
Есть ли способ добиться этого, не повторяя код для каждогоUnit
?
1 ответ
Вы можете передать общийDimension
введите, а затем используйтеMeasurementFormatter
.
struct ProvidedUnitFormatStyle<D: Dimension>: FormatStyle where D: Unit {
func format(_ measurement: Measurement<D>) -> String {
let formatter = MeasurementFormatter()
formatter.unitOptions = .providedUnit
return formatter.string(from: measurement)
}
}
extension FormatStyle {
static func providedUnit<D: Dimension>(for dimension: D.Type) -> Self where Self == ProvidedUnitFormatStyle<D> {
return ProvidedUnitFormatStyle<D>()
}
}
// Usage:
let distance = Measurement(value: 100, unit: UnitLength.meters)
let duration = Measurement(value: 60, unit: UnitDuration.seconds)
let distanceString = distance.formatted(.providedUnit(for: UnitLength.self))
let durationString = duration.formatted(.providedUnit(for: UnitDuration.self))
print(distanceString) // 100 m
print(durationString) // 60 sec