2
2
.
.
5
5
.
.
2
2
C
C
l
l
o
o
s
s
u
u
r
r
e
e
s
s
I
I
n
n
f
f
o
o
[
[
R
R
]
]
[
[
R
R
]
]
Signature
defines names and Data Types of Input Parameters (name:String, age:Int) (specifying Data Types is optional)
defines Data Type of Return Value (String) (specifying Data Type is optional)
arrow "->" inside Signature symbolizes that these Input Parameters are converted into this Output Parameter.
Since Closures can be stored inside Constants and Variables (including Input Function Parameters) Signature is used to say
what kind of Closure can be stored into a Constant or Variable.
For instance var name : Int says that Variable name can store Int Data Type.
Similarly var closure : (String, Int) -> (String) says that Variable closure can store Closure Data Type of specified Signature -
only Closures which accept String & Int as Input Parameters and return String.
When you store Closure inside Constant or Variable you can use them to call Closure (but without Named Parameters).
Parameter Names are only for internal use inside Closure's Body since Closure can't have Named Parameters when called.
Content
Closure Syntax
Closure Input Parameters (Parameters are not named)
Closure Return Value (Return single Variable or Tuple or use Input-Output Parameters)
S
S
y
y
n
n
t
t
a
a
x
x
[
[
R
R
]
]
Closure is declared
inside curly brackets { ... } { ... }
starting by Closure's Signature (name:String, age:Int) -> (String) (accepts 2 Parameters & returns String)
followed by Keyword in in
followed by Closure's Statements return ("\(name) is \(age) years old")
Closure Syntax
//DECLARE VARIABLE THAT CAN HOLD CLOSURE DATA TYPE (OF SPECIFIED SIGNATURE).
var closureVariable : (String, Int) -> (String) //Closure that accepts 2 Parameters & returns String
//DECLARE CLOSURE. ASSIGN CLOSURE TO VARIABLE.
closureVariable = { (name:String, age:Int) -> (String) in return("\(name) is \(age) years old") }
closureVariable = { (name , age ) -> (String) in return("\(name) is \(age) years old") }
closureVariable = { (name , age ) in return("\(name) is \(age) years old") }
closureVariable = { name , age in return("\(name) is \(age) years old") }
//CALL CLOSURE. STORE RETURN VALUE INTO VARIABLE.
var result : String = closureVariable("John", 20) //Closure can't have named Parameters.
//DISPLAY RESULT.
print(result)
C
C
l
l
o
o
s
s
u
u
r
r
e
e
I
I
n
n
p
p
u
u
t
t
P
P
a
a
r
r
a
a
m
m
e
e
t
t
e
e
r
r
s
s
Closure Input Parameters don't have External Parameter Names like Functions do.
That means that when you call a Closure you can only specify values for the Input Parameters.
Inside the Closure Body Input Parameters will be referenced either by using their
Internal Parameter Names as defined before the Keyword in { name, age in ...
indexes print("Hello \($0)")
Unlike in Functions, in Closures
Parameters are not named (when calling Closure)
Parameters can't have default values
Parameters can't be inout
E
E
x
x
a
a
m
m
p
p
l
l
e
e
In this example
first Closure uses Internal Parameter Names: name & age
second Closure uses Parameter indexes: $0 & $1
Closure Input Parameters
//STORE CLOSURE INTO VARAIBLE.
let greet1 : (String, Int) -> () = { name, age in print("\(name) is \(age) years old") }
let greet2 : (String, Int) -> () = { print("\($0) is \($1) years old") }
//CALL CLOSURE.
greet1("John", 20)
greet2("John", 20)
Output
John is 20 years old
John is 20 years old
I
I
g
g
n
n
o
o
r
r
e
e
I
I
n
n
p
p
u
u
t
t
P
P
a
a
r
r
a
a
m
m
e
e
t
t
e
e
r
r
If you don't intend to use certain Input Parameter inside Closure you can use '_' at its place.
Closure still needs to be called with all Input Parameter but those flagged with '_' can't be used inside the body.
Ignore first Parameter
//IGNORE FIRST PARAMETER.
let greet1 : (String, Int) -> () = { _, age in print("John is \(age) years old") }
//CALL CLOSURE.
greet1("Something", 20) //First parameter is ignored
C
C
l
l
o
o
s
s
u
u
r
r
e
e
R
R
e
e
t
t
u
u
r
r
n
n
V
V
a
a
l
l
u
u
e
e
Closures only have a single Return Value. Return Value Data Type is part of their Signature.
To return multiple Values from a Closure
Closure can return Tuple which is Collection of Values
Closure can return Instance of an Struct or Class
R
R
e
e
t
t
u
u
r
r
n
n
S
S
t
t
r
r
i
i
n
n
g
g
In this example Closure returns a String.
Closure has no Input Parameters since the first bracket is empty.
Return String
//STORE CLOSURE INTO VARAIBLE.
let greet : () -> (String) = {
return("Hello")
}
//CALL CLOSURE.
var result = greet()
//DISPLAY RETURN VALUE.
print(result)
R
R
e
e
t
t
u
u
r
r
n
n
T
T
u
u
p
p
l
l
e
e
In this example Closure returns a Tuple which is collection of Variable.
When Closure is called, Tuple Values can be immediately stored into separate Variables.
Or you can store returned Tuple into another Tuple Variable.
Tuple is a simpler alternative compared to struct since struct needs to be declared before you can use it.
Think of Tuple as a simplified temporary struct for a more convenient way of returning multiple values.
Return Tuple
//STORE CLOSURE INTO VARIABLE.
func test() -> (name: String, age: Int) {
return("John", 50)
}
//CALL CLOSURE.
var (nameRet, ageRet) = test() //Store Tuple values into Variables.
var result = test() //Store Tuple into another Tuple.
//DISPLAY RETURN VALUE.
print(result.0) //Access Tuple values through their indexes.
R
R
e
e
t
t
u
u
r
r
n
n
s
s
t
t
r
r
u
u
c
c
t
t
In this example Closure returns a struct with name and age Properties.
Since struct can contain any number of Variables/ Properties you can use this approach to effectively return multiple
values from a Closure even though you are just returning a single Instance of that struct.
Return struct
//DECLARE STRUCT.
struct Person {
var name : String
var age : Int
}
//STORE CLOSURE INTO VARAIBLE.
let greet : () -> (Person) = {
var person = Person(name: "John", age: 20)
return(person)
}
//CALL CLOSURE.
var person = greet()
//DISPLAY RETURN VALUE.
print(person)