我想创建一个属性包装器来适应众所周知的精度问题。但是,当我按照我所理解的使用和演示的方式使用@PropertyWrapper
时,我得到了以下错误:
Extra argument in call
Missing argument for parameter 'initialValue' in property wrapper initializer; add 'wrappedValue' and 'initialValue' arguments in '@MantissaClamping(...)'
我不明白我怎么在call,"我将小数赋值为包装后的值,并提供整数字面值作为尾号参数。
在说我有一个额外的参数后,另一个错误说我缺少一个参数。建议我把它们作为参数添加到属性包装器。在我看来,这将破坏属性包装器的全部目的,因为它将需要像这样的冗余代码……但即使这样也没用。
struct MantissaClampTestStruct {
@MantissaClamping(Decimal("0.000000000001")!, 14) var small: Decimal = Decimal("0.000000000001")!
}
我如何给属性分配一个文字值,并让它应用于属性包装器?在提供直接应用于属性包装器的int值时?
这是我的可复制代码,你可以把它放在操场上。
extension Decimal {
/// Rounds a value
/// - Parameters:
/// - roundingMode: up down plain or bankers
/// - scale: the number of digits result can have after its decimal point
/// - Returns: the rounded number
func rounded(_ roundingMode: NSDecimalNumber.RoundingMode = .bankers, scale: Int = 0) -> Self {
var result = Self()
var number = self
NSDecimalRound(&result, &number, scale, roundingMode)
return result
}
}
@propertyWrapper
struct MantissaClamping {
var value: Decimal
let mantissaCount: Int
init(initialValue value: Decimal, _ mantissaCount: Int) {
precondition(mantissaCount < 19 && mantissaCount >= 0)
self.value = value
self.mantissaCount = mantissaCount
}
var wrappedValue: Decimal {
get { value }
set { value = newValue.rounded(.down, scale: mantissaCount)}
}
}
struct MantissaClampTestStruct {
@MantissaClamping(14) var small: Decimal = Decimal("0.000000000001")!
}
根据文档:
当您包含属性包装器参数时,您还可以使用赋值指定初始值。Swift像对待
wrappedValue
实参一样对待赋值,并使用接受你包含的实参的初始化式。
它会把你的属性声明转换成这样的形式:
var small = MantissaClamping(wrappedValue: Decimal("0.000000000001")!, 14)
显然,这与任何初始化项都不匹配。
将参数标签重命名为wrappedValue
:
init(wrappedValue value: Decimal, _ mantissaCount: Int) {
并将string:
标签添加到Decimal
初始化器中,这是您错过的:
@MantissaClamping(14) var small: Decimal = Decimal(string: "0.000000000001")!
您可能还需要将初始值四舍五入:
init(wrappedValue value: Decimal, _ mantissaCount: Int) {
precondition(mantissaCount < 19 && mantissaCount >= 0)
// here
self.value = value.rounded(.down, scale: mantissaCount)
self.mantissaCount = mantissaCount
}