## DEV Community

Naveen Ragul B

Posted on • Updated on

# Swift - Function and Closures

## Function

• A Function can have 0 parameter to multiple parameter.
• A Function can have 0 return value(void) or multiple return value(using tuple) or even optional as return value.
• Each function parameter has both an argument label and a parameter name. By default, parameters use their parameter name as their argument label if argument label is not provided.
• If you don’t want an argument label for a parameter, write an underscore (_) instead
• You can define a default value for any parameter in a function by assigning a value to the parameter after that parameter’s type. If a default value is defined, you can omit that parameter when calling the function.

example :

``````func someFunction(parameterWithoutDefault: Int, parameterWithDefault: Int = 12) {
print("someFunction")
}
someFunction(parameterWithoutDefault: 3, parameterWithDefault: 6)
someFunction(parameterWithoutDefault: 4)
``````
• A variadic parameter (...) accepts zero or more values of a specified type. he values passed to a variadic parameter are made available within the function’s body as an array.

The first parameter that comes after a variadic parameter must have an argument label to avoid ambiguity.

example :

``````func arithmeticMean(_ numbers: Double...) -> Double {
var total: Double = 0
for number in numbers {
total += number
}
}
arithmeticMean(1, 2, 3, 4, 5)
``````
• Define that parameter as an in-out parameter if you want a function to modify a parameter’s value, because function parameters are constants by default. place an ampersand (&) directly before a variable’s name while passing a value to inout parameter.

In-out parameters can’t have default values, and variadic parameters can’t be marked as inout.

example :

``````func swapTwoInts(_ a: inout Int, _ b: inout Int) {
let temporaryA = a
a = b
b = temporaryA
}
var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
``````
• Use function types just like any other types.

example :

``````func addTwoInts(_ a: Int, _ b: Int) -> Int {
return a + b
}
var mathFunction: (Int, Int) -> Int = addTwoInts
``````
• Function Types can be used as a Parameter Types or Return types

## Closures

Closures are self-contained blocks of functionality that can be passed around and used in your code. Closures can capture and store references to any constants and variables from the context in which they’re defined.

• Closures take one of three forms:
1. Global functions are closures that have a name and don’t capture any values.
2. Nested functions are closures that have a name and can capture values from their enclosing function.
3. Closure expressions are unnamed closures written in a lightweight syntax that can capture values from their surrounding context.

### Closure Expressions

syntax :

``````{ (parameters) -> return type in
statements
}
``````

example :

``````let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in
return s1 > s2
})
``````
• shorthand closure syntax Inferring parameter and return value types from context. Implicit returns from single-expression closures. example :
``````reversedNames = names.sorted(by: { s1, s2 in return s1 > s2 } )
``````
• shorthand argument names

example :

``````reversedNames = names.sorted(by: { s1, s2 in s1 > s2 } )
``````
• Trailing closure - a closure expression to a function as the function’s final argument and the closure expression is long, it can be useful to write it as a trailing closure instead.

example :

``````reversedNames = names.sorted() { \$0 > \$1 }
``````

If a closure expression is provided as the function’s or method’s only argument , parentheses () can be omitted.

``````reversedNames = names.sorted { \$0 > \$1 }
``````

Closures and Functions Are Reference Types. Whenever you assign a function or a closure to a constant or a variable, you are actually setting that constant or variable to be a reference to the function or closure.

### Escaping Closure

A closure is said to escape a function when the closure is passed as an argument to the function, but is called after the function returns. write @escaping before the parameter’s type to indicate that the closure is allowed to escape.

example :

``````var completionHandlers: [() -> Void] = []
func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
completionHandlers.append(completionHandler)
}
``````

### Autoclosure

• An autoclosure is a closure that’s automatically created to wrap an expression that’s being passed as an argument to a function.
• It doesn’t take any arguments, and when it’s called, it returns the value of the expression that’s wrapped inside of it.

example :
without autoclosure :

``````var customersInLine = ["Chris", "Alex", "Ewa","Barry"]
func serve(customer customerProvider: () -> String) {
print("Now serving \(customerProvider())!") ////"Now serving Chris!"
}
serve(customer: { customersInLine.remove(at: 0) } )
``````

with autoclosure :

``````var customersInLine = ["Chris", "Alex", "Ewa", "Barry"]
func serve(customer customerProvider: @autoclosure () -> String) {
print("Now serving \(customerProvider())!") ////"Now serving Chris!"
}
serve(customer: customersInLine.remove(at: 0))
``````