如何从函数中 return 未指定的测量值 <T>?
How do I return an unspecified Measurement<T> from a function?
更新:好的,我很困惑。我的原始代码没有编译。在将其简化为最小示例的某个时刻,它显然开始起作用了。我已经重写了原始版本,现在我已经忘记了为什么它首先不起作用。打算将此问题标记为已解决。
我想弄清楚如何编写一个 returns 任意测量值的函数,而不必事先指定测量值的 UnitType。以下或多或少是我想做的,但它不编译。 (函数的参数无关紧要。)
func getValue(for x:Int) -> Measurement<Unit>? {
if x==1 {
return Measurement(value:5, unit:UnitSpeed.metersPerSecond)
} else {
return Measurement(value:2, unit:UnitLength.meters)
}
}
我不想关心单位是什么!测量封装了他们的单位,我想做的就是将它插入类似的东西:另一端的Text(reading?.unit.symbol ?? "")
。
func getValue(for measure:TrackedMeasure) -> some Measurement? {}
抱怨"Reference to generic type 'Measurement' requires arguments in <…>"
建议的修复是 func getValue(for measure:TrackedMeasure) -> some Measurement<Unit>? { }
,然后抱怨 "An 'opaque' type must specify only 'Any', 'AnyObject', protocols, and/or a base class"
似乎 没有测量协议,我不知道如何定义它。
我是否必须重新实施 Measurement 才能使这项工作正常进行?
enum TrackMeasure {
case speed
case distance
case time
}
func getValue(for measure: TrackMeasure) -> Measurement<Unit> {
switch measure {
case .speed:
return Measurement(value: 60, unit: UnitSpeed.milesPerHour)
case .distance:
return Measurement(value: 10, unit: UnitLength.miles)
case .time:
return Measurement(value: 6, unit: UnitDuration.minutes)
}
}
let speed = getValue(for: .speed)
let distance = getValue(for: .distance)
let time = getValue(for: .time)
Measurement<UnitType>
是一个通用类型,它不扩展公共基础 class 或符合公共协议,因此具体类型 Measurement<UnitLength>
与 Measurement<UnitSpeed>
.
绕过它的唯一方法是执行类型擦除之类的操作,并让它们都符合通用协议 AnyMeasurement
:
protocol AnyMeasurement {
var baseUnit: Unit { get }
var value: Double { get }
}
那么你可以让Measurement
符合AnyMeasurement
:
extension Measurement: AnyMeasurement {
// just need to return a base Unit, instead of a concrete UnitType
// value: Double { get } is already implemented by Measurement
var baseUnit: { self.unit }
}
然后,你可以这样做:
func randomMeasurement() -> AnyMeasurement {
let speed = Measurement(value: 10, unit: UnitSpeed.metersPerSecond)
let length = Measurement(value: 10, unit: UnitLength.meters)
return Bool.random() ? speed : length
}
print(randomMeasurement().baseUnit.symbol)
更新:好的,我很困惑。我的原始代码没有编译。在将其简化为最小示例的某个时刻,它显然开始起作用了。我已经重写了原始版本,现在我已经忘记了为什么它首先不起作用。打算将此问题标记为已解决。
我想弄清楚如何编写一个 returns 任意测量值的函数,而不必事先指定测量值的 UnitType。以下或多或少是我想做的,但它不编译。 (函数的参数无关紧要。)
func getValue(for x:Int) -> Measurement<Unit>? {
if x==1 {
return Measurement(value:5, unit:UnitSpeed.metersPerSecond)
} else {
return Measurement(value:2, unit:UnitLength.meters)
}
}
我不想关心单位是什么!测量封装了他们的单位,我想做的就是将它插入类似的东西:另一端的Text(reading?.unit.symbol ?? "")
。
func getValue(for measure:TrackedMeasure) -> some Measurement? {}
抱怨"Reference to generic type 'Measurement' requires arguments in <…>"
建议的修复是 func getValue(for measure:TrackedMeasure) -> some Measurement<Unit>? { }
,然后抱怨 "An 'opaque' type must specify only 'Any', 'AnyObject', protocols, and/or a base class"
似乎 没有测量协议,我不知道如何定义它。
我是否必须重新实施 Measurement 才能使这项工作正常进行?
enum TrackMeasure {
case speed
case distance
case time
}
func getValue(for measure: TrackMeasure) -> Measurement<Unit> {
switch measure {
case .speed:
return Measurement(value: 60, unit: UnitSpeed.milesPerHour)
case .distance:
return Measurement(value: 10, unit: UnitLength.miles)
case .time:
return Measurement(value: 6, unit: UnitDuration.minutes)
}
}
let speed = getValue(for: .speed)
let distance = getValue(for: .distance)
let time = getValue(for: .time)
Measurement<UnitType>
是一个通用类型,它不扩展公共基础 class 或符合公共协议,因此具体类型 Measurement<UnitLength>
与 Measurement<UnitSpeed>
.
绕过它的唯一方法是执行类型擦除之类的操作,并让它们都符合通用协议 AnyMeasurement
:
protocol AnyMeasurement {
var baseUnit: Unit { get }
var value: Double { get }
}
那么你可以让Measurement
符合AnyMeasurement
:
extension Measurement: AnyMeasurement {
// just need to return a base Unit, instead of a concrete UnitType
// value: Double { get } is already implemented by Measurement
var baseUnit: { self.unit }
}
然后,你可以这样做:
func randomMeasurement() -> AnyMeasurement {
let speed = Measurement(value: 10, unit: UnitSpeed.metersPerSecond)
let length = Measurement(value: 10, unit: UnitLength.meters)
return Bool.random() ? speed : length
}
print(randomMeasurement().baseUnit.symbol)