Swift 中的通用测量变量

问题描述 投票:0回答:1

我有这个代码

public class DoubleSensor: ObservableObject {
    private var cancellables: Set<AnyCancellable> = Set<AnyCancellable>()
    private(set) var sensor: any VEntity
    
    @Published public var state: doubleState = DefaultState.forDouble()
    
    public init(withSensor sensor: any VEntity) {
        self.sensor = sensor

    }
    
    private func updateData(fromState newState: doubleState) async {
        self.state = newState
    }
}

public final class TemperatureSensor: DoubleSensor {
    
    public var measurement: Measurement<UnitTemperature> {
        return Measurement(value: state.value, unit: .celsius)
    }
    
    public override init(withSensor sensor: any VEntity) {
        super.init(withSensor: sensor)
    }
}

public final class PercentageSensor: DoubleSensor {
    
    public var measurement: Measurement<UnitPercentage> {
        return Measurement(value: state.value, unit: UnitPercentage.percentage)
    }
    
    public override init(withSensor sensor: any VEntity) {
        super.init(withSensor: sensor)
    }
}

public final class EnergySensor: DoubleSensor {
    
    public var measurement: Measurement<UnitEnergy> {
        return Measurement(value: state.value, unit: .wattHours)
    }
    
    public override init(withSensor sensor: any VEntity) {
        super.init(withSensor: sensor)
    }
}

正如你所看到的,我有 3 个类继承自

DoubleSensor
类(它的一个小版本)。所有继承类都有一个特定于测量单位的测量变量。 如何创建通用类而不是特定类?

我可以创建类似的东西

public final class MeasurementSensor<T: Dimension>: DoubleSensor {

    public var measurement: Measurement<T> {
        return Measurement(value: state.value, unit: ???)
    }
    
    public override init(withSensor sensor: any VEntity) {
        super.init(withSensor: sensor)
    }

}

但我不知道如何设置单位值

编辑:

感谢Dávid Pásztor建议我进行编辑以改进问题:

VEntity
是一个协议,定义为

public protocol VEntity: Hashable, Equatable {
    var domain: String { get }
    var entityId: String { get }
    var entityName: String { get }
    var notificationName: NSNotification.Name { get }
}

doubleState
是一个类型别名,定义为

public typealias doubleState   = EntityState<Double, GenericAttributes>

其中

EntityState
是一个表示实体状态的对象,具有两个泛型属性:S(值)和A(属性),但我认为它的定义(不小)在这种情况下没有用

GeneriAttribute

public struct GenericAttributes: VAttribute {
    public let commonName: String
}

您的 DoubleSensor 子类只能使用硬编码的单位值吗?或者它们应该使用相同类型的任何值?

我的目标是摆脱多个继承类并仅创建一个包含给定单位测量值的类。 例如:

let temperatureSensor: MeasurementSensor = MeasurementSensor(withSensor: sensor01, andUnit: UnitTemperature, measuringIn: .celsius)
let energySensor: MeasurementSensor = MeasurementSensor(withSensor: sensor02, andUnit: UnitEnergy, measuringIn: .kilowattHours)

这只是给出最终结果的伪代码。我希望现在问题更清楚了。

swift generics measurement
1个回答
0
投票

您可以在每个子类中使用提供正确单位的类变量来提供正确的:

public final class MeasurementSensor<T: Dimension>: DoubleSensor {
    class var unit: T { fatalError("Not implemented!") }

    public var measurement: Measurement<T> {
        return Measurement(value: state.value, unit: Self.unit)
    }
    
    public override init(withSensor sensor: any VEntity) {
        super.init(withSensor: sensor)
    }
}

那么在你的子类中可能看起来像这样:

public final class TemperatureSensor: DoubleSensor {
    class var unit: T { .celsius }
    
    public override init(withSensor sensor: any VEntity) {
        super.init(withSensor: sensor)
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.