Reputation: 4687
Using swift 4.2 with xcode10 beta
I'm trying to create a swift class that stores as a field, a closure that will point to a member function of the class.
The idea is a variation to the Strategy pattern. I want to be able to change what function is called at runtime. In this example, the public f() function calls the internal closure. The closure should store either f_release or f_debug, where the later just add some debugging print statements:
class MyClass {
var n:Int = 0
var aFunc: (Int) -> ()
init() {
aFunc = f_release
}
public func f(number:Int) {
aFunc(number)
}
func f_release(number:Int) {
n = n + number
}
func f_debug(number:Int) {
print(n)
f_release(number:number)
print(n)
}
}
My problems comes at the initialization. In the example above the compiler complains: _'self' used in method call 'f_release' before all stored properties are initialized_
I've tried initializing the aFunc variable with a default value to fix this problem replacing line
var aFunc: (Int) -> ()
with line
var aFunc: (Int) -> () = f_release
However for that case, the compiler now complains with: Cannot convert value of type '(MyClass) -> (Int) -> ()' to specified type '(Int) -> ()'
What I am doing wrong? Thanks in advance
Upvotes: 1
Views: 1255
Reputation: 54795
Assigning the value inside the initializer cannot work, since you are trying to assign an instance property (or function in your specific case) to another instance property, but in the initializer, neither of them are guaranteed to be initialized.
You can solve your problem by declaring aFunc
as lazy. You won't need an initializer anymore either.
lazy var aFunc: (Int) -> () = f_release
Upvotes: 2
Reputation: 1148
Try this:
class MyClass {
var n:Int = 0
lazy var aFunc: (Int) -> () = f_release
public func f(number:Int) {
aFunc(number)
}
func f_release(number:Int) {
n = n + number
}
func f_debug(number:Int) {
print(n)
f_release(number:number)
print(n)
}
}
Upvotes: 2