I've made myself a playground-example to become familar with Property Wrappers.
Following code:
import Foundation
@propertyWrapper
struct Price {
private var price: Double
init() {
self.price = 0.0
}
var wrappedValue: Double {
get {
return self.price
}
set {
if newValue < 0.0 {
self.price = 0.0
} else if newValue > 10_000 {
return
} else {
self.price = newValue
}
}
}
}
struct Article {
var vendor: String
var name: String
@Price var price: Double
}
var display = Article(vendor: "Asus", name: "X127", price: 139.0)
/*
expression failed to parse:
error: Playground.playground:33:60: error: cannot convert value of type 'Double' to expected argument type 'Price'
var display = Article(vendor: "Asus", name: "X127", price: 139.0)
*/
print("\(display.vendor) Display costs \(display.price) Euro")
If I use ...
var display = Article(vendor: "Asus", name: "X127")
display.price = 129.99
print("\(display.vendor) Display costs \(display.price) Euro")
// Asus Display costs 129.99 Euro
... then it works fine.
What I'm I doing wrong with the constructor-initialization? What's the correct way to initialize the wrapper property?
What is going wrong within the first example in general?
You need an init that takes a value if you want the first example to work because otherwise the compiler won't know how to assign the value 139.0 to a Price
property
init(wrappedValue: Double) {
self.price = wrappedValue
}
Note that the parameter label is wrappedValue
to match the required property with the same name to make it possible to assign a default value.
And you also need to remove the existing init without parameters. This init is also the reason why your second example works since it gets called when there is no value for the price
argument in the Article
constructor meaning it works like a default value.