快速接受任何类型测量的函数

Ian*_*mis 3 polymorphism swift

Swift 实现的Measurement类型可用于在所需的指标中保存速度、高度等值。

例如:

// Going to explicitly type here so the question is clear

var speed: Measurement<UnitSpeed> = Measurement(value: 10, unit: UnitSpeed.metersPerSecond)
var altitude: Measurement<UnitLength> = Measurement(value: 500, unit: UnitLength.meters)

altitude.convert(to: UnitLength.feet)

print("500 meters is roughly \(Int(altitude.value)) feet")
// Prints: 500 meters is roughly 1640 feet
Run Code Online (Sandbox Code Playgroud)

然而,即使UnitLengthUnitSpeed都是 的子类Unit,使用这些类型的度量不能多态地传递到 swift 中的函数中。

例如,如果您传入类型为Measurement<UnitLength>或的对象,则以下函数不起作用Measurement<UnitSpeed>

func formatMeasurementAsString(measurement: Measurement<Unit>) -> String {
    return "\(Int(measurement.value)) \(measurement.unit.symbol)"
}
Run Code Online (Sandbox Code Playgroud)

将上面定义的speed或传递altitude到此函数中会产生以下错误:Cannot convert value of type 'Measurement<UnitSpeed>' to expected argument type 'Measurement<Unit>'

编辑:

因此,您可以在此示例中将speed和显式键入altitude为 type Measurement<Unit>。但是,如果您这样做,它们将失去非常有用的.convert(to:)功能,除非您Measurement<UnitLength>在转换之前将它们重新键入,这不是很有帮助。

Joa*_*son 6

您可以使函数通用

func formatMeasurementAsString<T: Unit>(measurement: Measurement<T>) -> String {
    return "\(Int(measurement.value)) \(measurement.unit.symbol)"
}
Run Code Online (Sandbox Code Playgroud)

例子

let length = Measurement(value: 180.0, unit: UnitLength.meters)
let speed = Measurement(value: 60, unit: UnitSpeed.kilometersPerHour)

print(formatMeasurementAsString(measurement: length))
print(formatMeasurementAsString(measurement: speed))
Run Code Online (Sandbox Code Playgroud)

180 米
60 公里/小时