I suspect I am missing something really obviously wrong here, so forgive me if I am being a bit thick.
All the examples I see for closures are for passing a closure to the array map function. I want to write my own function which takes a closure
This is what I am attempting
func closureExample(numberToMultiply : Int, myClosure : (multiply : Int) -> Int) -> Int
{
// This gets a compiler error because it says myClosure is not an Int
// I was expecting this to do was to invoke myClosure and return an Int which
// would get multiplied by the numberToMultiply variable and then returned
return numberToMultiply * myClosure
}
I am completely stumped on what I am doing wrong
Please help!!
Same way you call any function, with ().
return numberToMultiply * myClosure(multiply: anInteger)
A working example:
func closureExample(numberToMultiply : Int, myClosure : (multiply : Int) -> Int) -> Int {
return numberToMultiply * myClosure(multiply: 2)
}
closureExample(10, { num in
return 2*num
}) // 40
You treat a closure parameter just like a function named with the parameter's name. myClosure is the closure that needs to operate on numberToMultiply, so you want:
return myClosure(numberToMultiply)
That will pass numberToMultiply to your closure, and return the return value.
Related
Got it from Here
The Ultimate Closure
Finally, for the ultra parsimonious there is the following, without a byte wasted.
let testEquality9 : (Int, Int) -> Bool = (==)
Functions decalred with the func keyword are just closures with names. == is an example of one such named function. It takes 2 Int arguements, and returns a Bool telling you if they're equal. Its type is (Int, Int) -> Bool
testEquality9 is a closure, with the type (Int, Int) -> Bool. To it, the closure of the == function is assigned.
It can be called like this:
testEquality9(1, 2) // false
testEquality9(1, 1) // true
The key thing to draw from this is that functions are really just closures, so they can be used everywhere closures can be used.
For example, if you wanted to sort an array of Ints, you could use:
let ints = [3, 1, 4, 2]
let sorted = ints.sort{$0 < $1}
The sort(_:) method takes a closure that's of type (Int, Int) -> Bool. Our closure {$0 < $1} takes 2 Int params, and returns a Bool. So it fits that signiture.
However, we can make this code shorter. Because the < operator's function already has type (Int, Int) -> Bool, we can write this:
let sorted = ints.sort(<)
This passes the function (named closure) < in directly, without explicitly making our own closure to wrap around it.
This is not actually a closure, it's the equality operator that compares two integers stored into a variable.
Every operator is defined using a function and that function can be assigned to a variable. There is nothing else to it.
Operator Overloading:
func == (i : Int, j: Int) -> Bool {
return i == j
}
Should be equivalent to that.
As the others said, it's the abbreviation form of:
let testEquality9: (Int, Int) -> Bool = { (a: Int, b: Int) -> Bool in return a == b }
Reading from right to left, it creates a function that compares two Ints and assigns it to the constant testEquality9.
You need to mentally separate the 3 pieces:
The constant name:
let testEquality9
The constant type (it's a function type):
(Int, Int) -> Bool
And the value assigned to the constant:
(==)
OR, the long version:
{ (a: Int, b: Int) -> Bool in return a == b }
Enjoy Swift :)
Swift function parameters not accepted. Missing argument?
Calculate(theA, theB) //error: Missing argument label 'sideB:' in call
func Calculate(sideA: Int, sideB: Int) -> Int {
var ans = sideA + sideB
return ans;
}
You are missing the sideB: in your function call. I didn't want to rewrite your code (since you posted an image) but here's the working function call.
func calcButton(sender: AnyObject) {
let a: Int = 10
let b: Int = 11
calculate(a, sideB: b) //<-- Missing it here
}
func calculate(sideA: Int, sideB: Int) -> Int {
let a = sideA + sideB
return a
}
you might also want to have both variables in the function call so you can do this instead:
func calcButton(sender: AnyObject) {
let a: Int = 10
let b: Int = 11
calculate(sideA: a, sideB: b)
}
func calculate(sideA A: Int, sideB B: Int) -> Int {
return A + B
}
Just an FYI, use tab completion instead of writing out the function. Xcode will let you know all the function variables with placeholders so you can type them in.
you have missed the sideB param name in swift 3 first parameter is optional but second param is Mandatory that _ in there That’s an underscore. It changes the way the method is called. To illustrate this, here’s a very simple function:
func doStuff(thing: String) {
// do stuff with "thing"
}
It’s empty, because its contents don’t matter. Instead, let’s focus on how it’s called. Right now, it’s called like this:
doStuff(thing: "Hello")
You need to write the name of the thing parameter when you call the doStuff() function. This is a feature of Swift, and helps make your code easier to read. Sometimes, though, it doesn’t really make sense to have a name for the first parameter, usually because it’s built into the method name.
When that happens, you use the underscore character like this:
func doStuff(_ thing: String) {
// do stuff with "thing"
}
That means “when I call this function I don’t want to write thing, but inside the function I want to use thing to refer to the value that was passed in.
just learning about closures and nesting functions. Given the nested function below:
func printerFunction() -> (Int) -> () {
var runningTotal = 0
func printInteger(number: Int) {
runningTotal += 10
println("The running total is: \(runningTotal)")
}
return printInteger
}
Why does calling the func itself have an error, but when I assign the func to a constant have no error? Where is printAndReturnIntegerFunc(2) passing the 2 Int as a parameter to have a return value?
printerFunction(2) // error
let printAndReturnIntegerFunc = printerFunction()
printAndReturnIntegerFunc(2) // no error. where is this 2 going??
First of all you are getting error here printerFunction(2) because printerFunction can not take any argument and If you want to give an argument then you can do it like:
func printerFunction(abc: Int) -> (Int) -> (){
}
And this will work fine:
printerFunction(2)
After that you are giving reference of that function to another variable like this:
let printAndReturnIntegerFunc = printerFunction()
which means the type of printAndReturnIntegerFunc is like this:
that means It accept one Int and it will return void so this will work:
printAndReturnIntegerFunc(2)
(1) The function signature of printerFunction is () -> (Int) -> () which means it takes no parameter and returns another function, thats why when you try to call printerFunction(2) with a parameter gives you an Error.
(2) And the signature of the returned function is (Int) -> () which means it takes one parameter of Int and returns Void. So printAndReturnIntegerFunc(2) works
As a homage to Ruby I've been playing with an extension to Int that allows me to write useful code like this:
3.times { println("I keep holding on") }
This works well and here's the extension:
extension Int {
func times(fn: () -> ()) {
for i in 1...self {
fn()
}
}
}
Now, I'd like to pass the iteration number in to the closure, so I added a 2nd times() function to extension:
extension Int {
func times(fn: (iteration: Int) -> ()) {
for i in 1...self {
fn(iteration: i)
}
}
}
Which can be invoked like this:
5.times { (i: Int) -> () in println("Year \(i)") }
Now, according to the Swift docs,
It is always possible to infer the parameter types and return type
when passing a closure to a function as an inline closure expression.
As a result, you never need to write an inline closure in its fullest
form when the closure is used a function argument.
That sounds great, because then I can omit the parameter and return types, i.e. (i: Int) -> (), and just use the following syntax instead:
5.times { i in println("Year \(i)") }
But this leads to the following error: Error: Ambiguous use of 'times'
Is this way of invoking my times() function really ambigous to the compiler?
It is ambiguous. Both .times() methods can be used with the given closure expression if the parameter type of the closure is not known.
If you just write { i in println("Year \(i)") }, it is just a closure that takes one parameter of any type. Well, EVERY function type in Swift can be viewed as taking one parameter:
What you think of as zero-parameter functions actually take one parameter of type () (a.k.a. Void), of value (), that's why the type is written as () -> something
What you think of as multiple-parameter functions actually take one parameter of tuple type, a tuple of all the "multiple arguments", that's why the type is written as (foo, bar) -> something.
So, basically, your closure expression, without specifying the type of i, can be inferred to ANY function type in Swift that returns Void. The functions taken by both .times() methods match this -- for the first .times() method, it is inferred as a function of type () -> (), i.e. i has type (); for the second .times() method, it is inferred as a function of type Int -> (), i.e. i has type Int.
it looks like the ambiguity derives from the 2 extension methods having the same name. If you comment your first version of the times function, it works fine - if you comment the 2nd instead, surprisingly, you do not get an error from the compiler.
There is no ambiguity in my opinion, because the 2 functions have different signature - () -> () is different than (iteration: Int) -> (). I think it's a bug in the compiler, specifically type inference is failing.
Making the call explicit instead it works fine
5.times { (i: Int) -> () in println("Year \(i)") }
If the first version with the parameterless closure is commented, the line above compiles correctly, if instead the 2nd overload is commented, compilation fails as expected.
To prove that something is wrong in the compiler, this seems to work, whereas I'd expect a compilation error instead:
extension Int {
func times(fn: () -> ()) {
for i in 1...self {
fn()
}
}
}
5.times { i in println("Year \(i)") }
This is the output from the playground console:
Year ()
Year ()
Year ()
Year ()
Year ()
How to manipulate the closure parameters by their position in Swift.
I've tried in the following way, But, couldn't get the idea behind it, from the documentation.
var additionClosure = { (a : Int , b : Int )-> Int in
return ($0 + $1)
}
var a = 10
var b = 20
println("additionClosure \(additionClosure(a,b))")
Any help would be appreciated..... Well, Thanks in advance.
`The numbered argument format is used for when you don't want to create a named closure.
Example:
import Foundation
func add(a : Int, b : Int) -> Int {
return a + b
}
func test(a : (Int, Int) -> Int) {
println("result: \(a(10,20))")
}
test(add) // Calling test with a named closure
test({$0 + $1}) // Calling test with an anonymous closure
In the first case you define add with two parameters, and give them names a and b. In the second case, you don't even define the name of the closure, just the required functionality using $0 and $1