使用自定义setter和计算结构属性进行双向转换

时间:2016-06-29 23:24:23

标签: ios swift foundation data-conversion units-of-measurement

我根据给定的比例创建了一个结构来覆盖bean和water之间的转换。这是我目前如何定义这个

public struct Coffee {
    public var ratio:Double
    public var beans:Measurement<UnitMass>
    public var water:Measurement<UnitVolume> {
        return Measurement(value: (beans.value * ratio), unit: .milliliters)
    }
}

var cup = Coffee(ratio: 13.0, beans: Measurement(value: 30, unit: UnitMass.milligrams))
let computedWater = cup.water // 390 mL

这只能以一种方式工作,给定或更改bean。如何扩展结构以允许在更改水值时计算和设置bean?

期望的结果

cup.water = Measurement(value: 260, unit: .milliliters) // should set water and compute beans
print (cup.beans) // 20.0 mg

1 个答案:

答案 0 :(得分:0)

由于您具有相互依赖的变量,因此您无法直接使用计算属性,因为您需要能够存储“其他”项的值。

您可以使用私有支持变量来存储值和setter / getter代码来更新/检索这些代码。

您还需要实施特定的初始化工具,因为您不能再依赖自动成员初始化器。

public struct Coffee {
    private var _beans: Measurement<UnitMass>!
    private var _water: Measurement<UnitVolume>!

    public var ratio:Double
    public var beans:Measurement<UnitMass> {
        set {
            _beans = newValue
            _water = Measurement(value: (_beans.converted(to: .milligrams).value * ratio), unit: .milliliters)
        }
        get {
            return _beans
        }
    }

    public var water:Measurement<UnitVolume> {
        set {
            _water = newValue
            _beans = Measurement(value: _water.converted(to: .milliliters).value * (1/ratio)), unit: .milligrams)
        }
        get {
            return _water
        }
    }

    init(ratio: Double, beans: Measurement<UnitMass>) {
        self.ratio = ratio
        self.beans = beans
    }

    init(ratio: Double, water: Measurement<UnitVolume>) {
        self.ratio = ratio
        self.water = water 
    }
}

var cup = Coffee(ratio: 13.0, beans: Measurement(value: 30, unit: UnitMass.milligrams))
let computedWater = cup.water // 390 mL
print (cup.water)

cup.water = Measurement(value: 260, unit: .milliliters) // should set water and compute beans
print (cup.beans) // 20.0 mg
cup.water = Measurement(value: 0.26, unit: .liters)
print (cup.beans) // 20.0 mg

请注意,我还修改了公式,以确保使用正确的单位。