In my last question, I asked how to write setter for a subscript of a computed property in Swift. I think my question was not substantial enough to be understood. The answer given was either incorrect or complicated for a small task. After a long thought, I still think maybe a brighter man can offer a more inspiring answer.
To subside confusion, my question is if there is a shorthand setter declaration for a subscript of an array in Swift. Because there is shorthand setter declaration for an array in swift, but not its subscript.
A shorthand getter/setter declaration is
var center: Point {
get {
let centerX = origin.x + (size.width / 2)
let centerY = origin.y + (size.height / 2)
return Point(x: centerX, y: centerY)
}
set {
origin.x = newValue.x - (size.width / 2)
origin.y = newValue.y - (size.height / 2)
}
}
Basically, in a scenario where a set action for action[i]
will cause actionButton[i]
to be updated. There are basically two ways to do this quickly.
func setActionAtIndex(index:Int, forValue newValue:SomeClass){
action[index] = newValue
self.updateActionButtonAtIndex(index)
}
This solution above is easy to understand, however, it requires a function, which takes two lines of code, in one class. Not quite "Swift".
var action: [SomeClass] {
subscript(index:Int){
set(index:Int,newValue:SomeClass){
action[index] = newValue
//extra action to be performed
updateActionButtonAtIndex(index)
}
get{
return action[index]
}
}
}
Needless to say, this is absolutely wrong and this solution is nonexistent.
Why it is wrong?
Expected 'get', 'set', 'willSet', or 'didSet' keyword to start an accessor definition
I did think of another way, but I don't like it much. Use an extension to add another subscript to setter to Array - a setter that allows you to supply a callback. The problem with this approach is that you have remember to supply the callback! This puts the onus on whoever sets into the index, which is probably not what you had in mind. Still, it has the advantage, once configured, of brevity - and it takes O(0)
time:
extension Array {
subscript(ix:Int, f:(T,T,Int)->Void) -> T {
set {
let old = self[ix]
self[ix] = newValue
f(old,newValue,ix)
}
get {
return self[ix]
}
}
}
class Thing {
var arr : [Int] = [1, 2, 3]
func f (oldv:Int, newv:Int, ix:Int) {
println("changed \(oldv) to \(newv) at \(ix)")
}
}
var t = Thing()
t.arr[1,t.f] = 100 // "changed 2 to 100 at 1"