Tuples are considered value types. More info on tuples could be found in the documentation: developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html
Tuples group multiple values into a single compound value. The values within a tuple can be of any type and do not have to be of the same type as each other.
Tuples are created by grouping any amount of values:
let tuple = ("one", 2, "three")
// Values are read using index numbers starting at zero
print(tuple.0) // one
print(tuple.1) // 2
print(tuple.2) // three
Also individual values can be named when the tuple is defined:
let namedTuple = (first: 1, middle: "dos", last: 3)
// Values can be read with the named property
print(namedTuple.first) // 1
print(namedTuple.middle) // dos
// And still with the index number
print(namedTuple.2) // 3
They can also be named when being used as a variable and even have the ability to have optional values inside:
var numbers: (optionalFirst: Int?, middle: String, last: Int)?
//Later On
numbers = (nil, "dos", 3)
print(numbers.optionalFirst)// nil
print(numbers.middle)//"dos"
print(numbers.last)//3
Tuples can be decomposed into individual variables with the following syntax:
let myTuple = (name: "Some Name", age: 26)
let (first, second) = myTuple
print(first) // "Some Name"
print(second) // 26
This syntax can be used regardless of if the tuple has unnamed properties:
let unnamedTuple = ("uno", "dos")
let (one, two) = unnamedTuple
print(one) // "uno"
print(two) // "dos"
Specific properties can be ignored by using underscore (_
):
let longTuple = ("ichi", "ni", "san")
let (_, _, third) = longTuple
print(third) // "san"
Functions can return tuples:
func tupleReturner() -> (Int, String) {
return (3, "Hello")
}
let myTuple = tupleReturner()
print(myTuple.0) // 3
print(myTuple.1) // "Hello"
If you assign parameter names, they can be used from the return value:
func tupleReturner() -> (anInteger: Int, aString: String) {
return (3, "Hello")
}
let myTuple = tupleReturner()
print(myTuple.anInteger) // 3
print(myTuple.aString) // "Hello"
Occasionally you may want to use the same tuple type in multiple places throughout your code. This can quickly get messy, especially if your tuple is complex:
// Define a circle tuple by its center point and radius
let unitCircle: (center: (x: CGFloat, y: CGFloat), radius: CGFloat) = ((0.0, 0.0), 1.0)
func doubleRadius(ofCircle circle: (center: (x: CGFloat, y: CGFloat), radius: CGFloat)) -> (center: (x: CGFloat, y: CGFloat), radius: CGFloat) {
return (circle.center, circle.radius * 2.0)
}
If you use a certain tuple type in more than one place, you can use the typealias
keyword to name your tuple type.
// Define a circle tuple by its center point and radius
typealias Circle = (center: (x: CGFloat, y: CGFloat), radius: CGFloat)
let unitCircle: Circle = ((0.0, 0.0), 1)
func doubleRadius(ofCircle circle: Circle) -> Circle {
// Aliased tuples also have access to value labels in the original tuple type.
return (circle.center, circle.radius * 2.0)
}
If you find yourself doing this too often, however, you should consider using a struct
instead.
Tuples are useful to swap values between 2 (or more) variables without using temporary variables.
Given 2 variables
var a = "Marty McFly"
var b = "Emmett Brown"
we can easily swap the values
(a, b) = (b, a)
Result:
print(a) // "Emmett Brown"
print(b) // "Marty McFly"
var a = 0
var b = 1
var c = 2
var d = 3
(a, b, c, d) = (d, c, b, a)
print(a, b, c, d) // 3, 2, 1, 0
Use tuples in a switch
let switchTuple = (firstCase: true, secondCase: false)
switch switchTuple {
case (true, false):
// do something
case (true, true):
// do something
case (false, true):
// do something
case (false, false):
// do something
}
Or in combination with an Enum For example with Size Classes:
let switchTuple = (UIUserInterfaceSizeClass.Compact, UIUserInterfaceSizeClass.Regular)
switch switchTuple {
case (.Regular, .Compact):
//statement
case (.Regular, .Regular):
//statement
case (.Compact, .Regular):
//statement
case (.Compact, .Compact):
//statement
}