In Chris Eidhof's
recent post I learned that you can use willSet
and
didSet
on local var
s. This is just a quick write-up
to explore it a bit.
var s1 = "initial value" {
didSet {
print("changed s1 to:", s1)
}
}
print()
is called.
s1 = "new value"
s1 = "newer value"
Recording History
Here is another example, that keeps a history of previous values.
var history = [String]()
var s = "initial" {
willSet {
history.append(s)
}
}
s = "a"
s = "b"
s = "c"
s = "d"
print("history:", history)
Final Thoughts
I'm not sure if this is an intended feature, or some weird side effect of the implementation. And, I don't know what an actual good use of it is. But it sure is a neat trick! Also, you can tell this isn't a very common thing, because Xcode's auto-indent doesn't handle it very well.
let
variable.
let s = "initial" {
didSet { print("test") }
}
I'm not exactly sure what "observer properties" means, but at least it correctly points out that this only make sense on things that can actually change.
Follow Up
Turns out, there are might be some practical uses for this after all. My esteemed work colleague,
Marc Palmer had an inspired idea to
use this to implement a DSL, based on
his experience with Groovy. I'm familiar with similar tricks from Ruby (using
#instance_eval
and friends), but I never thought that kind of thing would be possible
in Swift.
Unfortunately, he noticed a problem (in an update in his post). It appears that multiple repeated
sets to the local var get optimized out, so only the last one actually triggers the
didSet
. So this technique isn't quite reliable yet. But maybe there is some way to
fix this, with some further experimentation.