使用自定义设置器和计算结构属性的两种方式转换
Two way conversion using custom setters and computed struct properties
我创建了一个结构来根据给定的比例涵盖豆类和水之间的转换。这是我目前如何定义这个
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
因为你有相互依赖的变量,你不能直接使用计算属性,因为你需要能够存储 'other' 项的值。
您可以使用私有后备变量来存储值和 setter/getter 代码 update/retrieve 这些。
您还需要实施特定的初始化器,因为您不能再依赖自动成员初始化器。
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
请注意,我还修改了您的公式,以确保使用正确的单位。
我创建了一个结构来根据给定的比例涵盖豆类和水之间的转换。这是我目前如何定义这个
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
因为你有相互依赖的变量,你不能直接使用计算属性,因为你需要能够存储 'other' 项的值。
您可以使用私有后备变量来存储值和 setter/getter 代码 update/retrieve 这些。
您还需要实施特定的初始化器,因为您不能再依赖自动成员初始化器。
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
请注意,我还修改了您的公式,以确保使用正确的单位。