Found myself in a situation where having newValue or some new currentValue variable would help in the body of didSet where currently only oldValue special variable is available:
Without it I need to use the name of the property explicitly which is visually somewhat more noisy, somewhat harder to parse and process mentally and somewhat more error prone:
If you've got a scenario where you must do something only after the value is set, this sort of copy and paste is still a good sign that you can consider refactoring.
The very powerful @dynamicMemberLookup feature allows you to write a wrapper type so that you can make sure that setting any property triggers calling the function you want, without requiring you to copy and paste your code over and over again:
// Storage type.
struct _S {
var a, b, c: String
}
// Wrapper type.
@dynamicMemberLookup
struct S {
var _s: _S
func f(_: String) {
print("Hello, World!")
}
subscript(dynamicMember keyPath: WritableKeyPath<_S, String>) -> String {
get { _s[keyPath: keyPath] }
set {
_s[keyPath: keyPath] = newValue
f(newValue)
}
}
}
You can even make the wrapping type generic so that multiple different struct types can have that functionality.
I can, just as I said it is "visually somewhat more noisy, somewhat harder to parse and process mentally and somewhat more error prone". It is analogous to using a function name instead of #function: