You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Functions are self-contained pieces of code that perform a specific task. You give each function a name that describes what it does, and you use this name to "call" the function whenever you need it to do its job. This makes your code clearer, shorter, and more organized.
7
8
8
-
foo
9
+
```swift
10
+
funcgreet() {
11
+
print("Hello World!")
12
+
}
13
+
14
+
greet()
15
+
```
16
+
17
+
Functions can accept parameters, which are values you pass into the function to customize its behavior. By defining parameters, you allow your function to work with different inputs each time it is called:
18
+
19
+
```swift
20
+
funcgreet(
21
+
name: String
22
+
) {
23
+
print("Hello, \(name)!")
24
+
}
25
+
greet(name: "Tibor")
26
+
greet(name: "Kitti")
27
+
```
28
+
29
+
You can customize how you use functions and make them easier to understand by adding custom **argument labels**. These labels appear before the parameter name and are separated by a space. They help make your function calls more readable and user-friendly:
30
+
31
+
```swift
32
+
funcgreet(
33
+
toname: String
34
+
) {
35
+
print("Hello, \(name)!")
36
+
}
37
+
38
+
greet(to: "Tibor")
39
+
```
40
+
41
+
If you do not want to use a label at all, place an underscore `_` before the parameter name. This allows you to call the function using just the parentheses and the argument, without any label. The function's behavior stays the same, so you can choose to show or hide argument labels based on what makes your code clearer and easier to read:
42
+
43
+
```swift
44
+
funcgreet(
45
+
_name: String
46
+
) {
47
+
print("Hello, \(name)!")
48
+
}
49
+
// calling the function
50
+
greet("Tibor")
51
+
```
52
+
53
+
When using default parameter values, you can omit that argument from the function call. If you do, the function will automatically use the default value you provided:
54
+
55
+
```swift
56
+
funcgreet(
57
+
toname: String="Guest"
58
+
) {
59
+
print("Hello, \(name)!")
60
+
}
61
+
62
+
greet()
63
+
greet(to: "Tibi")
64
+
```
65
+
66
+
Functions can also have more than one parameter:
67
+
68
+
```swift
69
+
funcsumNumbers(
70
+
_a: Int,
71
+
_b: Int
72
+
) {
73
+
let sum = a + b
74
+
print("Sum: ", sum)
75
+
}
76
+
// function call with two arguments: 42 and 69
77
+
sumNumbers(42, 69)
78
+
```
79
+
80
+
A variadic parameter in Swift lets a function accept zero or more values of a specific type, so you can pass any number of arguments you need. To define a variadic parameter, add `...` after the parameter's type:
81
+
82
+
```swift
83
+
funcsumNumbers(
84
+
_numbers: Int...
85
+
) {
86
+
var sum =0
87
+
for number in numbers {
88
+
sum += number
89
+
}
90
+
print("Sum: ", sum)
91
+
}
92
+
93
+
sumNumbers()
94
+
sumNumbers(42)
95
+
sumNumbers(42, 69)
96
+
sumNumbers(42, 69, 4, 2, 6, 9)
97
+
```
98
+
99
+
Parameter overloading allows you to define multiple functions with the same name, as long as they have different parameter types or a different number of parameters. This is also known as function overloading:
9
100
10
101
```swift
11
-
let x =5
12
-
let y =5
13
-
var z =0
102
+
// function with Int type parameter
103
+
funcdisplayValue(value: Int) {
104
+
print("Integer value:", value)
105
+
}
14
106
15
-
z = x + y // addition
16
-
print(z) // => 10
107
+
// function with String type parameter
108
+
funcdisplayValue(value: String) {
109
+
print("String value:", value)
110
+
}
17
111
18
-
z = x - y // subtraction
19
-
print(z) // => 0
112
+
// function call with String type parameter
113
+
displayValue(value: "Swift")
20
114
21
-
z = x * y // multiplication
22
-
print(z) // => 25
115
+
// function call with Int type parameter
116
+
displayValue(value: 2)
117
+
```
23
118
24
-
z = x / y // division
25
-
print(z) // => 1
119
+
Swift will automatically choose the correct function to call based on the type and number of arguments you provide. It uses both the number and types of parameters to determine which version of the function to execute.
26
120
121
+
A function return type specifies the type of value a function gives back after it finishes executing. The return value is the actual result that the function produces:
27
122
28
-
var x =10
123
+
```swift
124
+
funcsquare(number: Int) ->Int {
125
+
let result = number * number
126
+
return result
127
+
}
29
128
30
-
x +=2// addition
31
-
print(x) // => 12
129
+
let result =square(number: 4)
130
+
print(result)
32
131
33
-
x -=2// subtraction
34
-
print(x) // => 10
132
+
let doubled = result *2
133
+
print(doubled)
134
+
```
35
135
36
-
x *=2// multiplication
37
-
print(x) // => 20
136
+
For functions that have only a single expression, you can leave out the `return` keyword and simply write the expression itself:
38
137
39
-
x /=2// division
40
-
print(x) // => 10
138
+
```swift
139
+
funcsquare(number: Int) ->Int {
140
+
number * number
141
+
}
41
142
```
42
143
43
-
bar
144
+
A function can also return a tuple, allowing you to return multiple values at once. Tuples group several values into a single compound value, which can be useful when you want to provide more than one result from a function:
44
145
45
-
```sh
46
-
swift main.swift
146
+
```swift
147
+
funcminMax(
148
+
numbers: [Int]
149
+
) -> (min: Int, max: Int) {
150
+
let minValue = numbers.min() ??0
151
+
let maxValue = numbers.max() ??0
152
+
return (min: minValue, max: maxValue)
153
+
}
154
+
155
+
let result =minMax(numbers: [3, 7, 2, 9])
156
+
print(result.min)
157
+
print(result.max)
47
158
```
48
159
49
-
baz
160
+
In this example, the `minMax` function returns both the minimum and maximum values from an array as a tuple.
A closure in Swift is a block of code that you can store in a variable, pass around in your program, and run whenever you need. You can think of closures as function-like values — they work very much like functions, but they do not always need a name.
7
8
8
-
foo
9
+
```swift
10
+
let greet = {
11
+
print("Hello, world")
12
+
}
13
+
greet()
14
+
```
15
+
16
+
Closures can also have parameters. You also need to define the type of the parameters, just like you'd do when defining the parameters of a function. The syntax is just slightly different:
17
+
18
+
```swift
19
+
let greet = { (name: String) in
20
+
print("Hello, \(name)")
21
+
}
22
+
23
+
greet("Tibi")
24
+
```
25
+
26
+
Closures can also return values:
27
+
28
+
```swift
29
+
let sum = { (num1: Int, num2: Int) ->Intin
30
+
return num1 + num2
31
+
}
32
+
33
+
let res =sum(2, 3)
34
+
print(res) // 5
35
+
```
36
+
37
+
Here is an example of a function and a closure, both performing the same task:
38
+
39
+
```swift
40
+
funcsum(num1: Int, num2: Int) ->Int {
41
+
number + number
42
+
}
43
+
44
+
let add = { (num1: Int, num2: Int) ->Intin
45
+
num1 + num2
46
+
}
47
+
```
48
+
49
+
It is possible to move out the closure type information from the definition and explicitly tell the type of the `add` constant instead. The following example is the exact same as the previous one, but we've moved the type information to the left:
50
+
51
+
```swift
52
+
let add: ((Int, Int) ->Int) = { num1, num2 in
53
+
num1 + num2
54
+
}
55
+
```
56
+
57
+
If you have a function with the same signature (exact same parameter types and return types), you can use that function as a closure:
9
58
10
59
```swift
11
-
let x =5
12
-
let y =5
13
-
var z =0
60
+
funcadd(a: Int, b: Int) ->Int {
61
+
a + b
62
+
}
14
63
15
-
z = x + y // addition
16
-
print(z) // => 10
64
+
let sum: (Int, Int) ->Int= add
65
+
sum(2, 3) // 5
66
+
```
17
67
18
-
z = x - y // subtraction
19
-
print(z) // => 0
68
+
By assigning a function to a variable like sum, you _treat behavior_ as _data_. This means you can change what sum actually does at runtime:
20
69
21
-
z = x * y // multiplication
22
-
print(z) // => 25
70
+
```swift
71
+
funcadd(a: Int, b: Int) ->Int { a + b }
72
+
funcmultiply(a: Int, b: Int) ->Int { a * b }
23
73
24
-
z = x / y // division
25
-
print(z) // => 1
74
+
var operation: (Int, Int) ->Int= add
75
+
print(operation(3, 4))
26
76
77
+
operation = multiply
78
+
print(operation(3, 4))
79
+
```
27
80
28
-
var x =10
81
+
By the way, in Swift, every identifier must be unique within its scope. That means you can't define a variable and a function with the same name in the same place—Swift won't know which one you mean. You get a compiler error.
29
82
30
-
x +=2// addition
31
-
print(x) // => 12
32
83
33
-
x -=2// subtraction
34
-
print(x) // => 10
84
+
A function parameter can be a closure, in the example below it takes two integers and returns an integer after performing a specific operation on them:
35
85
36
-
x *=2// multiplication
37
-
print(x) // => 20
86
+
```swift
87
+
funcperformOperation(
88
+
_a: Int,
89
+
_b: Int,
90
+
_op: ((Int, Int) ->Int)
91
+
) {
92
+
print(op(a, b))
93
+
}
94
+
95
+
performOperation(3, 1, { a, b in a + b })
96
+
performOperation(3, 1, { a, b in a - b })
97
+
```
38
98
39
-
x /=2// division
40
-
print(x) // => 10
99
+
Once you feel more comfortable with closures, you can switch to writing shorter, more concise versions that are easier to read and maintain. Here are some examples to show how you can make closures more concise as you get comfortable with the syntax:
100
+
101
+
```swift
102
+
// longest form, explicit types and return keyword
103
+
performOperation(3, 1, { (a: Int, b: Int) ->Intinreturn a + b })
104
+
// no explicit types
105
+
performOperation(3, 1, { a, b inreturn a + b })
106
+
// no explicit return keyword
107
+
performOperation(3, 1, { a, b in a + b })
108
+
// most simple, shorthand argument names called "trailing closure syntax:
109
+
performOperation(3, 2, { $0*$1 })
41
110
```
42
111
43
-
bar
112
+
When a function's last parameter is a closure, you can use trailing closure syntax to make the function call simpler and easier to read:
44
113
45
-
```sh
46
-
swift main.swift
114
+
```swift
115
+
performOperation(3, 2) { $0*$1 } // 6
47
116
```
48
117
49
-
baz
118
+
You can also use multiple trailing closure syntax when a function has more than one closure parameter:
119
+
120
+
```swift
121
+
funcgetPointFromClosures(
122
+
x: () ->Int,
123
+
y: () ->Int
124
+
) -> (x: Int, y: Int) {
125
+
(x(), y())
126
+
}
127
+
128
+
let point =getPointFromClosures { 42 } y: { 69 }
129
+
130
+
print(point.x, point.y)
131
+
```
132
+
133
+
Because operators are also functions in Swift, you can use them as closure parameters just like you would with regular functions:
134
+
135
+
```swift
136
+
funcmul(_a: Int, b: Int) ->Int {
137
+
a * b
138
+
}
139
+
performOperation(3, 2, mul)
140
+
141
+
performOperation(3, 2, +)
142
+
performOperation(3, 2, *)
143
+
```
144
+
145
+
By using operators as closure parameters, your Swift code can become simpler and easier to follow, especially in cases where you want to perform standard operations in a flexible way.
0 commit comments