属性 包装器初始值设定项中缺少参数 'initialValue' 的参数;在中添加 'wrappedValue' 和 'initialValue' 参数

Missing argument for parameter 'initialValue' in property wrapper initializer; add 'wrappedValue' and 'initialValue' arguments in

我想创建一个 属性 包装器来解决众所周知的精度问题。但是,当我按照我的理解使用 @PropertyWrapper 来使用和演示 here 时,出现以下错误:

Extra argument in call
Missing argument for parameter 'initialValue' in property wrapper initializer; add 'wrappedValue' and 'initialValue' arguments in '@MantissaClamping(...)'

我不明白我怎么会有“调用中的额外参数”,我将小数指定为包装值,并提供整数文字作为尾数参数。

在说我有一个额外的参数之后,另一个错误说我缺少一个参数。并建议我认为建议我从字面上将它们作为参数添加到 属性 包装器......在我看来这将破坏 属性 包装器的全部目的,因为它需要像这样的冗余代码...... .但即使这样也行不通。

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")!
}

根据 docs:

When you include property wrapper arguments, you can also specify an initial value using assignment. Swift treats the assignment like a wrappedValue argument and uses the initializer that accepts the arguments you include.

所以它会将您的 属性 声明翻译成如下内容:

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
}