Functions
## Learning Objectives
- Create functions with parameters
- Return values from functions
- Use inout parameters
- Master closures and higher-order functions
- Understand function types
## Basic Functions
### Function Declaration
```swift
func sayHello() {
print("Hello!")
}
sayHello() // Calls the function
```
### With Return Type
```swift
func greet() -> String {
return "Hello, World!"
}
let message = greet()
print(message)
```
## Parameters
### Single Parameter
```swift
func square(number: Int) -> Int {
return number * number
}
let result = square(number: 5) // 25
```
### Multiple Parameters
```swift
func add(a: Int, b: Int) -> Int {
return a + b
}
let sum = add(a: 3, b: 4) // 7
```
### Parameter Labels
```swift
func greet(name: String) {
print("Hello, \(name)!")
}
greet(name: "Alice")
```
### External and Local Names
```swift
func greet(to name: String) {
print("Hello, \(name)!")
}
greet(to: "Alice") // External: to, Local: name
```
### Omitting External Names
```swift
func add(_ a: Int, _ b: Int) -> Int {
return a + b
}
add(3, 4) // No external names needed
```
### Default Parameters
```swift
func greet(_ name: String, greeting: String = "Hello") {
print("\(greeting), \(name)!")
}
greet("Alice") // Hello, Alice!
greet("Bob", greeting: "Hi") // Hi, Bob!
```
### Variadic Parameters
```swift
func sum(numbers: Int...) -> Int {
var total = 0
for number in numbers {
total += number
}
return total
}
sum(numbers: 1, 2, 3, 4, 5) // 15
sum(numbers: 10, 20) // 30
```
## Return Values
### Single Return
```swift
func multiply(a: Int, b: Int) -> Int {
return a * b
}
```
### Multiple Returns (Tuples)
```swift
func divide(_ a: Int, by b: Int) -> (quotient: Int, remainder: Int) {
return (a / b, a % b)
}
let result = divide(10, by: 3)
print(result.quotient) // 3
print(result.remainder) // 1
```
### Optional Return
```swift
func findFirst(odd: [Int]) -> Int? {
for num in odd {
if num % 2 == 1 {
return num
}
}
return nil
}
let first = findFirst(odd: [2, 4, 6, 8, 9])
if let odd = first {
print("Found odd: \(odd)")
}
```
## inout Parameters
Modify original values:
```swift
func swap(_ a: inout Int, _ b: inout Int) {
let temp = a
a = b
b = temp
}
var x = 10
var y = 20
swap(&x, &y)
print("x: \(x), y: \(y)") // x: 20, y: 10
```
### inout with Arrays
```swift
func doubleValues(_ array: inout [Int]) {
for i in 0.. Int
func add(_ a: Int, _ b: Int) -> Int {
return a + b
}
// () -> Void
func sayHello() {
print("Hello!")
}
```
### Assign to Variable
```swift
func multiply(_ a: Int, _ b: Int) -> Int {
return a * b
}
let operation: (Int, Int) -> Int = multiply
let result = operation(3, 4) // 12
```
### Pass as Argument
```swift
func applyOperation(_ fn: (Int, Int) -> Int, a: Int, b: Int) -> Int {
return fn(a, b)
}
let result = applyOperation(multiply, a: 3, b: 4) // 12
```
### Return from Function
```swift
func getOperation(_ type: String) -> (Int, Int) -> Int {
switch type {
case "add":
return { $0 + $1 }
case "multiply":
return { $0 * $1 }
default:
return { $0 - $1 }
}
}
let op = getOperation("add")
op(5, 3) // 8
```
## Closures
### Basic Closure Expression
```swift
let greeting = { (name: String) in
print("Hello, \(name)!")
}
greeting("Alice")
```
### Shorthand Syntax
```swift
let numbers = [1, 2, 3, 4, 5]
// Full closure
let doubled = numbers.map({ (n: Int) -> Int in
return n * 2
})
// With type inference
let doubled2 = numbers.map({ n in n * 2 })
// Trailing closure
let doubled3 = numbers.map { n in n * 2 }
// Shorthand arguments
let doubled4 = numbers.map { $0 * 2 }
```
### Capturing Values
```swift
func makeCounter() -> () -> Int {
var count = 0
return {
count += 1
return count
}
}
let counter = makeCounter()
counter() // 1
counter() // 2
counter() // 3
```
## Higher-Order Functions
### Map
Transform elements:
```swift
let numbers = [1, 2, 3, 4, 5]
let squared = numbers.map { $0 * $0 } // [1, 4, 9, 16, 25]
let strings = numbers.map { String($0) } // ["1", "2", "3", "4", "5"]
```
### Filter
Select elements:
```swift
let numbers = [1, 2, 3, 4, 5, 6]
let evens = numbers.filter { $0 % 2 == 0 } // [2, 4, 6]
let greaterThan3 = numbers.filter { $0 > 3 } // [4, 5, 6]
```
### Reduce
Combine elements:
```swift
let numbers = [1, 2, 3, 4, 5]
let sum = numbers.reduce(0) { $0 + $1 } // 15
let product = numbers.reduce(1) { $0 * $1 } // 120
// Shorthand
let sum2 = numbers.reduce(0, +) // 15
```
### FlatMap
Flatten arrays:
```swift
let nested = [[1, 2], [3, 4], [5, 6]]
let flat = nested.flatMap { $0 } // [1, 2, 3, 4, 5, 6]
```
### CompactMap
Remove nils:
```swift
let optionals: [Int?] = [1, nil, 3, nil, 5]
let nonNil = optionals.compactMap { $0 } // [1, 3, 5]
```
### Chaining
```swift
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let result = numbers
.filter { $0 % 2 == 0 } // [2, 4, 6, 8, 10]
.map { $0 * $0 } // [4, 16, 36, 64, 100]
.reduce(0, +) // 220
```
## Recursion
### Recursive Function
```swift
func factorial(_ n: Int) -> Int {
if n <= 1 {
return 1
}
return n * factorial(n - 1)
}
factorial(5) // 120
```
### Fibonacci
```swift
func fibonacci(_ n: Int) -> Int {
if n <= 1 {
return n
}
return fibonacci(n - 1) + fibonacci(n - 2)
}
fibonacci(10) // 55
```
## Nested Functions
```swift
func outerFunction() {
var x = 10
func innerFunction() {
x += 5
print("Inner: \(x)")
}
innerFunction()
print("Outer: \(x)")
}
outerFunction()
// Inner: 15
// Outer: 15
```
## Summary
- Functions declared with `func` keyword
- Parameters have external and local names
- Default, variadic, and `inout` parameters available
- Return single values or tuples (including optionals)
- Function types: `(paramTypes) -> returnType`
- Closures: anonymous functions with `in` keyword
- Higher-order: map, filter, reduce, flatMap, compactMap
- Capture values from surrounding scope
- Support recursion and nested functions
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →