Swift Functions
Swift functions are independent blocks of code that perform specific tasks.
Swift uses a unified syntax to represent functions from simple C-style functions to complex Objective-C-style methods.
-
Function Declaration: Informs the compiler about the function's name, return type, and parameters.
-
Function Definition: Provides the actual body of the function.
Swift functions include parameter types and return value types:
Function Definition
Swift defines functions using the func keyword.
When defining a function, you can specify one or more input parameters and a return type.
Each function has a name that describes its functionality. The function is called using its name and corresponding parameter values. The order of parameter passing must match the parameter list.
The order of actual arguments passed must match the formal parameter list, and the return type of the function is defined after ->.
Syntax
func funcname(parameters) -> returntype
{
Statement1
Statement2
……
Statement N
return parameters
}
Example
Below, we define a function named tutorialpro
with a parameter of type String
and a return value also of type String
:
import Cocoa
func tutorialpro(site: String) -> String {
return (site)
}
print(tutorialpro(site: "www.tutorialpro.org"))
The output of the above program is:
www.tutorialpro.org
Function Call
We can call a function using its name and corresponding parameter values. The order of parameter passing must match the parameter list.
Below, we define a function named tutorialpro
with a parameter site
of type String
. When we call the function, the actual argument passed must also be of type String
. The argument is passed into the function body and directly returned, with the return type being String
.
import Cocoa
func tutorialpro(site: String) -> String {
return (site)
}
print(tutorialpro(site: "www.tutorialpro.org"))
The output of the above program is:
www.tutorialpro.org
Function Parameters
Functions can accept one or more parameters, which are included within the function's parentheses, separated by commas.
The following example passes the site name name
and site address site
to the function tutorialpro
:
import Cocoa
func tutorialpro(name: String, site: String) -> String {
return name + site
}
print(tutorialpro(name: "tutorialpro.org:", site: "www.tutorialpro.org"))
print(tutorialpro(name: "Google:", site: "www.google.com"))
The output of the above program is:
tutorialpro.org:www.tutorialpro.org
Google:www.google.com
Functions Without Parameters
We can create functions without parameters.
Syntax:
func funcname() -> datatype {
return datatype
}
Example
import Cocoa
func sitename() -> String {
return "tutorialpro.org"
}
print(sitename())
The output of the above program is:
tutorialpro.org
Tuples as Function Return Values
Function return types can be strings, integers, floats, etc.
Tuples are similar to arrays, but the elements in a tuple can be of any type and are enclosed in parentheses.
You can use tuple types to return multiple values as a compound value from a function.
The following example defines a function named minMax(_:)
that finds the minimum and maximum values in an array of integers.
import Cocoa
func minMax(array: [Int]) -> (min: Int, max: Int) {
var currentMin = array[0]
var currentMax = array[0]
for value in array[1..<array.count] {
if value < currentMin {
currentMin = value
} else if value > currentMax {
currentMax = value
}
}
return (currentMin, currentMax)
}
} else if value > currentMax {
currentMax = value
}
return (currentMin, currentMax) }
let bounds = minMax(array: [8, -6, 2, 109, 3, 71]) print("The minimum value is (bounds.min), and the maximum value is (bounds.max)")
The `minMax(_:)` function returns a tuple containing two `Int` values labeled as `min` and `max`, allowing them to be accessed by name when querying the function's return value.
The output of the above program is:
The minimum value is -6, and the maximum value is 109
If you are unsure if the returned tuple is non-nil, you can return an optional tuple type.
You can define an optional tuple by placing a question mark after the tuple type's closing parenthesis, such as `(Int, Int)?` or `(String, Int, Bool)?`
Note that `(Int, Int)?` is different from tuples containing optional types like `(Int?, Int?)`. The optional tuple type means the entire tuple is optional, not just each individual element within the tuple.
The previous `minMax(_:)` function returns a tuple containing two `Int` values. However, it does not perform any safety checks on the array parameter. If the `array` parameter is an empty array, the `minMax(_:)` function, as defined above, would trigger a runtime error when trying to access `array[0]`.
To safely handle the "empty array" issue, rewrite the `minMax(_:)` function to use an optional tuple return type and return `nil` when the array is empty:
```swift
import Cocoa
func minMax(array: [Int]) -> (min: Int, max: Int)? {
if array.isEmpty { return nil }
var currentMin = array[0]
var currentMax = array[0]
for value in array[1..<array.count] {
if value < currentMin {
currentMin = value
} else if value > currentMax {
currentMax = value
}
}
return (currentMin, currentMax)
}
if let bounds = minMax(array: [8, -6, 2, 109, 3, 71]) {
print("The minimum value is \(bounds.min), and the maximum value is \(bounds.max)")
}
The output of the above program is:
The minimum value is -6, and the maximum value is 109
Functions with No Return Values
Here is another version of the tutorialpro(_:)
function, which takes a parameter for the tutorialpro.org website URL, does not specify a return value type, and directly outputs a String
value instead of returning it:
import Cocoa
func tutorialpro(site: String) {
print("tutorialpro.org website: \(site)")
}
tutorialpro(site: "http://www.tutorialpro.org")
The output of the above program is:
tutorialpro.org website: http://www.tutorialpro.org
Function Parameter Names
Function parameters have both an external parameter name and a local parameter name.
Local Parameter Names
Local parameter names are used within the function's implementation.
func sample(number: Int) {
print(number)
}
In the above example, number
is a local parameter name and can only be used within the function.
import Cocoa
func sample(number: Int) {
print(number)
}
sample(number: 1)
sample(number: 2)
sample(number: 3)
The output of the above program is:
1
2
3
External Parameter Names
You can specify an external parameter name before the local parameter name, separated by a space, which is used for passing the parameter when calling the function.
Here you can define the following function parameters and call it:
import Cocoa
func pow(firstArg a: Int, secondArg b: Int) -> Int {
var res = a
for _ in 1..<b {
res = res * a
}
print(res)
return res
}
pow(firstArg: 5, secondArg: 3)
The output of the above program is:
125
return res
}
pow(firstArg:5, secondArg:3)
The output of the above program is:
125
Variadic Parameters
A variadic parameter can accept zero or more values. You can use a variadic parameter to specify that the parameter can be passed a varying number of input values when the function is called.
A variadic parameter is defined by inserting three dots (...
) after the parameter's type name.
import Cocoa
func vari<N>(members: N...){
for i in members {
print(i)
}
}
vari(members: 4,3,5)
vari(members: 4.5, 3.1, 5.6)
vari(members: "Google", "Baidu", "tutorialpro")
The output of the above program is:
4
3
5
4.5
3.1
5.6
Google
Baidu
tutorialpro
Constants, Variables, and I/O Parameters
By default, parameters defined in a function are constant parameters; you can only read from them, not modify them.
To declare a variable parameter, prefix the parameter definition with the inout
keyword, which allows the parameter's value to be changed within the function.
For example:
func getName(_ name: inout String).........
At this point, the name
value can be changed within the function.
By default, parameter passing is done by value, not by reference. So changes to the parameter inside the function do not affect the original argument. The passed parameter is just a copy of the original.
When passing a parameter as an in-out parameter, you need to prefix the parameter name with an &
symbol to indicate that it can be modified by the function.
Example
import Cocoa
func swapTwoInts(_ a: inout Int, _ b: inout Int) {
let temporaryA = a
a = b
b = temporaryA
}
var x = 1
var y = 5
swapTwoInts(&x, &y)
print("x is now \(x), y is now \(y)")
The swapTwoInts(_:_:)
function simply swaps the values of a
and b
. It first stores the value of a
in a temporary constant temporaryA
, then assigns the value of b
to a
, and finally assigns the value of temporaryA
to b
.
Note that someInt
and anotherInt
are prefixed with &
when passed to the swapTwoInts(_:_:)
function.
The output of the above program is:
x is now 5, y is now 1
Function Types and Usage
Every function has a specific function type, made up of the parameter types and the return type of the function.
func inputs(no1: Int, no2: Int) -> Int {
return no1/no2
}
The inputs
function type has two parameters of type Int
(no1, no2) and returns a value of type Int
.
Here is an example:
import Cocoa
func inputs(no1: Int, no2: Int) -> Int {
return no1/no2
}
print(inputs(no1: 20, no2: 10))
print(inputs(no1: 36, no2: 6))
The output of the above program is:
2
6
The above function defines two parameters of type Int
and returns a value of type Int
.
Next, let's look at a function that defines parameters of type String
and returns a value of type String
.
func inputstr(name: String) -> String {
return name
}
A function can also be defined with no parameters and no return value, as shown below:
import Cocoa
func inputstr() {
print("tutorialpro.org")
print("www.tutorialpro.org")
}
inputstr()
The output of the above program is:
tutorialpro.org
www.tutorialpro.org
Using Function Types
In Swift, you use function types just like any other types. For example, you can define a constant or variable to be of a function type and assign an appropriate function to it:
var addition: (Int, Int) -> Int = sum
Explanation:
"Define a variable called addition
with parameters and return type both being Int
, and assign it to the sum
function."
Since sum
and addition
have the same type, the above operation is valid.
Now, you can call the assigned function using addition
:
import Cocoa
func sum(a: Int, b: Int) -> Int {
return a + b
}
var addition: (Int, Int) -> Int = sum
print(addition(4, 5))
The output of the above program is:
9
func sum(a: Int, b: Int) -> Int {
return a + b
}
var addition: (Int, Int) -> Int = sum
print("Output result: \(addition(40, 89))")
The program execution output is:
Output result: 129
Function Types as Parameter Types and Return Types
We can pass a function as an argument to another function:
import Cocoa
func sum(a: Int, b: Int) -> Int {
return a + b
}
var addition: (Int, Int) -> Int = sum
print("Output result: \(addition(40, 89))")
func another(addition: (Int, Int) -> Int, a: Int, b: Int) {
print("Output result: \(addition(a, b))")
}
another(addition: sum, a: 10, b: 20)
The program execution output is:
Output result: 129
Output result: 30
Nested Functions
Nested functions refer to functions defined within another function, and the outer function can call the inner function.
Here is an example:
import Cocoa
func calcDecrement(forDecrement total: Int) -> () -> Int {
var overallDecrement = 0
func decrementer() -> Int {
overallDecrement -= total
return overallDecrement
}
return decrementer
}
let decrem = calcDecrement(forDecrement: 30)
print(decrem())
The program execution output is:
-30