Reputation: 2119
I am currently taking an iTunes U course on Swift programming, and am stuck on this code sample below:
switch operation {
case "×": performOperation { $0 * $1 }
case "÷": performOperation { $1 / $0 }
default: break
}
func performOperation(operation: (Double, Double) -> Double) {
if operandQueue.count >= 2 {
displayValue = operation(operandQueue.removeLast(),operandQueue.removeLast())
enter()
}
}
My question is: how does { $0 * $1 }
get passed to operation: (Double, Double) -> Double)
? This code works but I just don't see how it works. The arguments being passed do not appear to be in the correct order. From how I read the declaration of performOperation, the proper order for calling it should be '*', $0, $1
. I just don't see the correspondence
as being in the correct order. What am I missing here?
Upvotes: 0
Views: 252
Reputation: 154603
performOperation
takes a function/closure which takes two Double
s and returns a Double
. It could have been called like this:
performOperation( {(a: Double, b: Double) -> Double in return a * b } )
You can leave off the types since the called function specifies them:
performOperation( {(a, b) in return a * b } )
And you can eliminate the return
since it is only one line:
performOperation( {(a, b) in a * b } )
Then you can use the default argument names $0 and $1:
performOperation( { $0 * $1 } )
Finally, you can use trailing closure syntax to eliminate the parentheses:
performOperation { $0 * $1 }
The final version is equivalent to the first. It just uses several shortcuts.
Upvotes: 3
Reputation: 2400
performOperation { $0 * $1 }
is a simplified concise form of performOperation({(s1 : Double, s2 : Double) in return s1 * s2 })
.
Two key terms here are capture
and inference
. Swift is able to "capture" the values of the parameters s1 and s2 and to "infer" the type of the return
value of performOperation
ETA: following through. This can be further simplified and made more concise as follows:
case "×": performOperation(*)
Since *
already exists as a function which takes 2 Doubles and returns a Double. Everything else works via inference.
Upvotes: 0
Reputation: 70098
(Double, Double) -> Double
means it's a function that takes two Doubles as arguments and returns a Double.
This function itself is the argument for performOperation
.
When you call performOperation { $0 * $1 }
, the {}
part is the function and $0
and $1
are its two arguments: (Double, Double)
.
Upvotes: 0
Reputation: 2147
The reason this work is because in the closures the name of parameter 1 is $0
and the name of the second is $1
. So, in the closure what it did was take those and perform some operation on them that returns a double
Upvotes: 0
Reputation: 5669
Here's the declaration of performOperation:
func performOperation(operation: (Double, Double) -> Double)
This is a function (func
) called performOperation
, which takes a generic function as its only argument. This function must take two doubles ((Double, Double)
, aka $0
and $1
) and return a double (-> Double
). {$0 * $1}
is a function that satisfies all of these constraints.
Does that clear things up a bit?
Upvotes: 0