Functions in Swift 2

Functions are reusable pieces of code that perform a specific task. They take input, do something with it, and either change some value, print something out, or output a result. Swift’s functions are like functions in any other programming language in this way, so if you’re familiar with functions in C or another language, much of this chapter will be somewhat of a review.

But don’t skip it! Even though the ideas will be similar to what you already know, the implementation is different, the syntax at first might seem very odd, and functions themselves are different in some fundamental ways. Later in the chapter, we’ll be discussing closures: a type of function very important in Swift and iOS programming. We’ll also be talking about value and reference types and how they’re treated in functions. So stick with me here… in some ways, your understanding of iOS programming will depend on how well you understand functions.

Syntax

Swift’s function syntax is expressive. A function declaration / definition begins with the keyword func, has a name, a parameter list enclosed in parentheses, and a return value following the → operator (a – followed by a >). Here’s the declaration for a function named add that takes two Int parameters (a and b), and returns their sum as an Int:

func add(a:Int, b:Int) -> Int 
{ 
   return a + b
}

 

The return statement is a control transfer statement: in this case, it returns the sum of a and b. Also note that the parameter names use the same syntax as that used in naming the values of a tuple. All function parameters must be annotated with their types.

Now that we’ve defined the add function over integers, we can use it in a program:

var sum = add(3, b: 6)

and now the fun begins. Why have we labeled b: in the function call? Because we have to. Why do we have to label b, but not a? Because the first parameter label of a function isn’t used when we call the function. But why? Because I said so. More importantly, because Swift says so. So calm down, and just accept this for now: All arguments in the parameters list of a function definition must be labeled. When we call the function, we omit the first label, but use all the others. There are reasons the syntax is this way. Also, there are ways to override this behavior, and we’ll learn them.

The main reason the syntax of a function call omits the first argument has to do with the readability of the function call. Suppose we rewrote the add function this way:

func add(a:Int, to:Int) -> Int { return a + to

}
Now we can call the function this way:

var sum = add(3, to:6)

which is very nearly natural language. After all, that’s what we’re doing: adding 3 to 6 and getting a result. We’ll come back to these semantic issues later.

If you think about it, there are four permutations of parameter lists and return values. Here’s an example of each:

//no parameters, no return value

func sayHi() { print("Hello")

}

//calling

sayHi()

//parameters, no return value

func printSumOf(a:Int, and:Int) { print(a + and)

}

//calling

printSumOf(3, and: 7)

//no parameters, with return value

func getHiString() -> String { return "Hi"

}

//calling

var greeting = getHiString()

//parameters and return value

func productOf(a:Int, and:Int) -> Int { return a * and

}

//calling

var number = productOf(2, and: 5)

If a function returns a value, it defines its type in the → clause, and must have a return statement. If there is no return value, there is no → clause, and the return statement is optional. An empty parameter list must be given: (), even if there are no parameters to the function. Pretty simple stuff, so far, right? I mean the syntax itself might not be what you’re used to, but once you get used to that, it all makes sense, right? OK. Let’s keep going.

A function can return multiple values by returning a tuple containing those values. If you’re used to C functions, I might have just blown your mind. But it’s true. Here’s a function that takes a tuple of Ints as a parameter and returns a tuple of Ints with the values swapped:

func swapInts(t:(Int, Int)) -> (Int, Int) { return (t.1, t.0)

}

The parameter t: is a tuple of two integers. Since we return (t.1, t.0) we’ve just swapped the members of the tuple. Here’s how we’d call the function:

print(swapInts((2, 7)))
We’re passing the tuple (2, 7) to the function and printing the result: (7, 2). Pretty cool, huh? No

pointers, no temp values, just a simple swap of two integers.

Leave a Comment: