Chapter 8 Tuples
A tuple is an ordered list of elements. Tuples provide a way to group multiple values together. Many languages provide tuples as a native data type. Commonly there are two ways of accessing the data in a tuple: by position or by name. Swift provides tuples as a native data type along with the ability to access the tuples data both by name and by position.
In Swift a tuple can consist of multiple different types. Tuples are ordered and elements of tuples can also be named. So we can access elements of a tuple both by position and name, and we can deconstruct data into a tuple using the assignment operator. Lets go through some examples of how we use tuples in Swift.
Tuples are defined using ()
. We can decompose a tuple into its parts using the assignment operator.
1 var coordinates = (54.2667, 8.4833)
2
3 let (lat, lon) = coordinates
4
5 let(latt, _) = coordinates
6
7 print("Lattitude is \(lat)")
8 print("Lattitude is \(latt)")
Here we create a tuple consisting of 2 floats. We can assign the contents to lat
and lon
using assignment (line 3). If we don’t care about all of the contents of the tuple we can use _
to indicate fields that we don’t care about. In line 5 we just extract the value of the first element of the tuple into a constant - the _
indicates that we don’t care about the second.
1 var response = (code: 502, message: "Bad Gateway")
2
3 response.0 // 502
4 response.1 // "Bad Gateway"
5
6 response.code // 502
7 response.message // "Bad Gateway"
8
9 response = (502, 502) // Type Error
We can also access the elements of a tuple by position or by name. Here we define a tuple with named fields. We do this by providing the names as keys when we create the tuple (line 1). In this example we’ve named the first field code
, and the second field message
.
We can access the elements by position using .0
, .1
etc (lines 3-4). But since we named these fields when we created the tuple, we can also access these fields using their names. (lines 6 and 7)
Tuples in Swift are typed. When we created our tuple at line 1 here, Swift inferred its type as (Int, String)
. This means that whenever we try to create or update a tuple, our assignment must match the type signature. So if we try to assign 2 integers to response (line 9) we get an error because the second element of the tuple must be a string.
In fact, tuples in Swift are not just typed, they can also be types in their own right. The type signature of a tuple is the composite of the types of its individual elements. So in the example above, the type of the response tuple is (Int, String)
.
We can use a tuple anywhere in Swift that it expects a type. So for example, function argument types or function return types can be tuples.
1 func getNewMail () -> (code: Int, message: String) {
2 return (200, "OK")
3 }
4
5 typealias Response = (code: Int, message: String)
6
7 var result:Response
8 result = (500, "Internal Server Error")
9
10 func getNewMail2 () -> Response {
11 return (200, "OK")
12 }
13
14 getNewMail()
15 getNewMail2()
One common use-case for tuples is to return multiple values from a function. For example, a function to retrieve a URL might return a tuple with both the response code and a message. In this example we create a function that returns a tuple, which consists of an Int
and a String
(line 1). Thus the tuple type becomes the return type for the function. We can use typealias
to name this type. At line 5 above we create a named tuple type called Response
, which consists of 2 fields named code
, an integer, and message
, a string. Now we can use Response
in our type declarations instead of describing the tuple type in full each time. This lets us declare and reuse our own composite types by combining existing types and improve the readability of our code.
Lines 7 and 8 above show an example where we declare a variable called result, which has a type of our new Response
type, and assign it a new value. Line 10 shows how we can now use our Response
type as the return for the function we wrote at line 1.