I have a struct wrapping a var data:[T]
that also supplies some statistics on the internal Array. One statistic is the max value, which can be an expensive operation because it requires searching the every element to determine the max value-- so I'd like to cache the max value and only recalculate it if I need to:
private mutating func getMax()->T? {
if let m=maxValue {
return m
}
else if data.count>0 {
maxValue=data.maxElement()
return maxValue
}
else {
return nil
}
}
That seems to work fine as a method, but I can't figure out how to do the same thing as a computed property.
var max:T? {return getMax()}
leads to a complaint that the accessor needs to be marked "mutating" because getMax() is mutating (actually I'd put the getMax code into the property accessor, but it's easier to not rewrite the code here).
Xcode suggests I rewrite the code thusly:
var max:T? mutating {return getMax()}
which then flags another problem and Xcode suggests putting a semicolon before mutating which leads to a suggestion to put another semicolon after mutating and then yet another semicolon after mutating and it's clear the compiler isn't even trying to help but just has a semicolon fetish.
Is there a way to write a computed property that permits caching values or am I stuck writing this as a method?
Structs are not copied on mutation. They may be mutated in-place. But every variable is a new copy (including passing the struct value as a function parameter). In functional languages values are truly immutable (so in order to change oven's temperature you need create a new oven in a new kitchen in a new house).
Computed properties are part of a family of property types in Swift. Stored properties are the most common which save and return a stored value whereas computed ones are a bit different. A computed property, it's all in the name, computes its property upon request.
In swift, classes are reference type whereas structures and enumerations are value types. The properties of value types cannot be modified within its instance methods by default. In order to modify the properties of a value type, you have to use the mutating keyword in the instance method.
In short, the first is a stored property that is initialized via a closure, with that closure being called only one time, when it is initialized. The second is a computed property whose get block is called every time you reference that property.
The correct syntax, despite the compiler's suggestions, would be:
var max:T? {
mutating get {return getMax()}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With