Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
326 views
in Technique[技术] by (71.8m points)

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

I'd like to create a property wrapper to accommodate the well known precision issues. However, when I use the @PropertyWrapper as I understand it to be used and demonstrated here, I get the following errors:

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

I don't see how I have an "extra argument in call," I assign the decimal as the wrapped value, and I provide the integer literal as the mantissa argument.

After saying I have an extra argument, the other error says I'm missing an argument. And suggesting I think suggesting that I literally add them as arguments to the property wrapper...That would defeat the whole purpose of property wrappers in my eyes, because it would require redundant code like this...But even this doesn't work.

struct MantissaClampTestStruct {
    @MantissaClamping(Decimal("0.000000000001")!, 14) var small: Decimal = Decimal("0.000000000001")!
}

How can I assign a literal value to the property, and let that apply to the property wrapper? While providing the int value that directly applies to the property wrapper?

Here is my reproducible code you can put in a playground.

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")!
}
question from:https://stackoverflow.com/questions/66056717/missing-argument-for-parameter-initialvalue-in-property-wrapper-initializer-a

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

According to the 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.

So it translates your property declaration into something like:

var small = MantissaClamping(wrappedValue: Decimal("0.000000000001")!, 14)

Obviously, this doesn't match any of your initialisers.

Just rename the parameter label to wrappedValue:

init(wrappedValue value: Decimal, _ mantissaCount: Int) {

And also add the string: label to the Decimal initialiser, which you have missed:

@MantissaClamping(14) var small: Decimal = Decimal(string: "0.000000000001")!

You might also want to round the initial value too:

init(wrappedValue value: Decimal, _ mantissaCount: Int) {
    precondition(mantissaCount < 19 && mantissaCount >= 0)

    // here
    self.value = value.rounded(.down, scale: mantissaCount)
    self.mantissaCount = mantissaCount
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...