Reputation: 5414
I want to create a class' method that takes some parameters and a function. And I want that function parameter to have a default value. So I'm doing:
class Calculator {
func operate(n1: Int, n2: Int, _ f: ((Int, Int) -> Int)? = add) -> Int {
return (f ?? add)(n1, n2)
}
func add(n1: Int, n2: Int) -> Int {
return n1 + n2
}
}
Here, f
is a function parameter that can be passed (or not, as it is optional). I want add to be the default value for f, so if you do:
Calculator().operate(n1: 10, n2: 20)
// not passing f causes add to be called
Problem: this does not compile, it's telling me that the correct type for f
should be: (Calculator) -> (Int, Int) -> Int
. That is: add
is a method of class Calculator, which makes perfect sense.
But is there a way to express that method as a function?
I can define a external function like:
func externalAdd(n1: Int, n2: Int) -> Int {
return n1 + n2
}
Then everything works as expected is I change the default value of f
:
class Calculator {
func operate(n1: Int, n2: Int, _ f: ((Int, Int) -> Int)? = externalAdd) -> Int {
return (f ?? add)(n1, n2)
}
func add(n1: Int, n2: Int) -> Int {
return n1 + n2
}
}
Ideas? Is this possible?
Upvotes: 2
Views: 485
Reputation: 146
If you try this:
class Calculator {
var addFunction: ((Int, Int) -> Int) {
return add
}
func operate(n1: Int, n2: Int, _ f: ((Int, Int) -> Int)? = addFunction) -> Int {
func add(n1: Int, n2: Int) -> Int {
return n1 + n2
}
return (f ?? add)(n1, n2)
}
func add(n1: Int, n2: Int) -> Int {
return n1 + n2
}
}
The compiler error will be "Cannot use instance member 'addFunction' as a default parameter".
The reason is that in swift you cannot use instance variables in function declarations.
Hope it helps
Upvotes: 0
Reputation: 539965
In
func operate(n1: Int, n2: Int, _ f: ((Int, Int) -> Int)? = add) -> Int
add
is evaluated as Calculator.add
which has the type
(Calculator) -> (Int, Int) -> Int
as explained in Instance Methods are “Curried” Functions in Swift.
One option is to use nil
as the default value (since you do optional chaining anyway later):
class Calculator {
func operate(n1: Int, n2: Int, _ f: ((Int, Int) -> Int)? = nil) -> Int {
return (f ?? add)(n1, n2)
}
func add(n1: Int, n2: Int) -> Int {
return n1 + n2
}
}
Another option is to make the default function a static
method, and the function parameter non-optional:
class Calculator {
func operate(n1: Int, n2: Int, _ f: ((Int, Int) -> Int) = add) -> Int {
return f(n1, n2)
}
static func add(n1: Int, n2: Int) -> Int {
return n1 + n2
}
}
Upvotes: 2