There is an updated edition of this book available! View Latest Edition

# 2 Types & Operations Written by Matt Galloway

You can unlock the rest of this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.

Now that you know how to perform basic operations and manipulate data using these operations, it’s time to learn more about types. Formally, a type describes a set of values and the operations that can be performed on them. In this chapter, you’ll learn about handling different types, including strings which allow you to represent text. You’ll learn about converting between types and you’ll also be introduced to type inference which makes your life as a programmer a lot simpler. Finally, you’ll learn about tuples which allow you to make your own types made up of multiple values of any type.

## Type conversion

Sometimes you’ll have data in one format and need to convert it to another. The naïve way to attempt this would be like so:

``````var integer: Int = 100
var decimal: Double = 12.5
integer = decimal
``````

Swift will complain if you try to do this and spit out an error on the third line:

`Cannot assign value of type 'Double' to type 'Int'`

Some programming languages aren’t as strict and will perform conversions like this silently. Experience shows this kind of silent, automatic conversion is a source of software bugs and often hurts performance. Swift disallows you from assigning a value of one type to another and avoids these issues.

Remember, computers rely on us programmers to tell them what to do. In Swift, that includes being explicit about type conversions. If you want the conversion to happen, you have to say so!

Instead of simply assigning, you need to explicitly say that you want to convert the type. You do it like so:

``````integer = Int(decimal)
``````

The assignment on the third line now tells Swift unequivocally that you want to convert from the original type, `Double`, to the new type, `Int`.

Note: In this case, assigning the decimal value to the integer results in a loss of precision: The `integer` variable ends up with the value `12` instead of `12.5`. This is why it’s important to be explicit. Swift wants to make sure you know what you’re doing and that you may end up losing data by performing the type conversion.

### Operators with mixed types

So far, you’ve only seen operators acting independently on integers or doubles. But what if you have an integer that you want to multiply by a double?

``````let hourlyRate: Double = 19.5
let hoursWorked: Int = 10
let totalCost: Double = hourlyRate * hoursWorked
``````
``````let totalCost: Double = hourlyRate * Double(hoursWorked)
``````

### Type inference

Up to this point in this book, each time you’ve seen a variable or constant declared it’s been accompanied by a type annotation. You may be asking yourself why you need to bother writing the `: Int` and `: Double`, since the right hand side of the assignment is already an `Int` or a `Double`. It’s redundant, to be sure; your crazy-clever brain can see this without too much work.

``````let typeInferredInt = 42
``````

``````let typeInferredDouble = 3.14159
``````

``````let wantADouble = 3
``````
``````let actuallyDouble = Double(3)
``````
``````let actuallyDouble: Double = 3
``````
``````let actuallyDouble = 3 as Double
``````

### Mini-exercises

1. Create a constant called `age1` and set it equal to `42`. Create a constant called `age2` and set it equal to `21`. Check using Option-click that the type for both has been inferred correctly as `Int`.
2. Create a constant called `avg1` and set it equal to the average of `age1` and `age2` using the naïve operation `(age1 + age2) / 2`. Use Option-click to check the type and check the result of `avg1`. Why is it wrong?
3. Correct the mistake in the above exercise by converting `age1` and `age2` to type `Double` in the formula. Use Option-click to check the type and check the result of `avg1`. Why is it now correct?

## Strings

Numbers are essential in programming, but they aren’t the only type of data you need to work with in your apps. Text is also an extremely common data type, such as people’s names, their addresses, or even the words of a book. All of these are examples of text that an app might need to handle.

### How computers represent strings

Computers think of strings as a collection of individual characters. In Chapter 1 of this book, you learned that numbers are the language of CPUs, and all code, in whatever programming language, can be reduced to raw numbers. Strings are no different!

### Unicode

In isolation, a computer is free to choose whatever character set mapping it likes. If the computer wants the letter a to equal the number 10, then so be it. But when computers start talking to each other, they need to use a common character set.

## Strings in Swift

Swift, like any good programming language, can work directly with characters and strings. It does so through the data types `Character` and `String`, respectively. In this section, you’ll learn about these data types and how to work with them.

### Characters and strings

The `Character` data type can store a single character. For example:

``````let characterA: Character = "a"
``````
``````let characterDog: Character = "🐶"
``````
``````let stringDog: String = "Dog"
``````
``````let stringDog = "Dog" // Inferred to be of type String
``````

### Concatenation

You can do much more than create simple strings. Sometimes you need to manipulate a string, and one common way to do so is to combine it with another string.

``````var message = "Hello" + " my name is "
let name = "Matt"
message += name // "Hello my name is Matt"
``````
``````let exclamationMark: Character = "!"
message += String(exclamationMark) // "Hello my name is Matt!"
``````

### Interpolation

You can also build up a string by using interpolation, which is a special Swift syntax that lets you build a string in a way that’s easy to read:

``````message = "Hello my name is \(name)!" // "Hello my name is Matt!"
``````
``````let oneThird = 1.0 / 3.0
let oneThirdLongString = "One third is \(oneThird) as a decimal."
``````

### Multi-line strings

Swift has a neat way to express strings that contain multiple lines. This can be rather useful when you need to put a very long string in your code.

``````let bigString = """
You can have a string
that contains multiple
lines
by
doing this.
"""
print(bigString)
``````
``````You can have a string
that contains multiple
lines
by
doing this.
``````

### Mini-exercises

1. Create a string constant called `firstName` and initialize it to your first name. Also create a string constant called `lastName` and initialize it to your last name.
2. Create a string constant called `fullName` by adding the `firstName` and `lastName` constants together, separated by a space.
3. Using interpolation, create a string constant called `myDetails` that uses the `fullName` constant to create a string introducing yourself. For example, my string would read: `"Hello, my name is Matt Galloway."`.

## Tuples

Sometimes data comes in pairs or triplets. An example of this is a pair of (x, y) coordinates on a 2D grid. Similarly, a set of coordinates on a 3D grid is comprised of an x-value, a y-value and a z-value. In Swift, you can represent such related data in a very simple way through the use of a tuple.

``````let coordinates: (Int, Int) = (2, 3)
``````
``````let coordinates = (2, 3)
``````
``````let coordinatesDoubles = (2.1, 3.5)
// Inferred to be of type (Double, Double)
``````
``````let coordinatesMixed = (2.1, 3)
// Inferred to be of type (Double, Int)
``````
``````let x1 = coordinates.0
let y1 = coordinates.1
``````
``````let coordinatesNamed = (x: 2, y: 3)
// Inferred to be of type (x: Int, y: Int)
``````
``````let x2 = coordinatesNamed.x
let y2 = coordinatesNamed.y
``````
``````let coordinates3D = (x: 2, y: 3, z: 1)
let (x3, y3, z3) = coordinates3D
``````
``````let coordinates3D = (x: 2, y: 3, z: 1)
let x3 = coordinates3D.x
let y3 = coordinates3D.y
let z3 = coordinates3D.z
``````
``````let (x4, y4, _) = coordinates3D
``````

### Mini-exercises

1. Declare a constant tuple that contains three `Int` values followed by a `Double`. Use this to represent a date (month, day, year) followed by an average temperature for that date.
2. Change the tuple to name the constituent components. Give them names related to the data that they contain: `month`, `day`, `year` and `averageTemperature`.
3. In one line, read the day and average temperature values into two constants. You’ll need to employ the underscore to ignore the month and year.
4. Up until now, you’ve only seen constant tuples. But you can create variable tuples, too. Change the tuple you created in the exercises above to a variable by using `var` instead of `let`. Now change the average temperature to a new value.

## A whole lot of number types

You’ve been using `Int` to represent whole numbers. An `Int` is represented with 64 bits on most modern hardware and with 32 bits on older, or more resource-constrained systems. Swift provides many more number types that use different amounts of storage. For whole numbers, you can use the explicit signed types `Int8`, `Int16`, `Int32`, `Int64`. These types consume 1, 2, 4, and 8 bytes of storage respectively. Each of these types use 1 bit to represent the sign.

``````let a: Int16 = 12
let b: UInt8 = 255
let c: Int32 = -100000

let answer = Int(a) + Int(b) + Int(c)  // answer is an Int
``````

## Type aliases

A useful feature of Swift is being able to create your own type which is actually an alias of another type. What this means you can do is give a more useful name to your type that describes what it is, but actually underneath it’s just another type. This is known as a type alias.

``````typealias Animal = String
``````
``````let myPet: Animal = "Dog"
``````
``````typealias Coordinates = (Int, Int)
let xy: Coordinates = (2, 4)
``````

## A peek behind the curtains: Protocols

Even though there are a dozen different numeric types, they are pretty easy to understand and use, because they all roughly support the same operations. In other words, once you know how to use an `Int`, using any one of the flavors is straight-forward.

## Challenges

Before moving on, here are some challenges to test your knowledge of types and operations. It is best if you try to solve them yourself, but solutions are available if you get stuck. These came with the download or are available at the printed book’s source code link listed in the introduction.

### Challenge 1: Coordinates

Create a constant called `coordinates` and assign a tuple containing two and three to it.

### Challenge 2: Named coordinate

Create a constant called `namedCoordinate` with a `row` and `column` component.

### Challenge 3: Which are valid?

Which of the following are valid statements?

``````let character: Character = "Dog"
let character: Character = "🐶"
let string: String = "Dog"
let string: String = "🐶"
``````

### Challenge 4. Does it compile?

``````let tuple = (day: 15, month: 8, year: 2015)
let day = tuple.Day
``````

### Challenge 5: Find the error

What is wrong with the following code?

``````let name = "Matt"
name += " Galloway"
``````

### Challenge 6: What is the type of `value`?

What is the type of the constant named `value`?

``````let tuple = (100, 1.5, 10)
let value = tuple.1
``````

### Challenge 7: What is the value of month?

What is the value of the constant named `month`?

``````let tuple = (day: 15, month: 8, year: 2015)
let month = tuple.month
``````

### Challenge 8: What is the value of `summary`?

What is the value of the constant named `summary`?

``````let number = 10
let multiplier = 5
let summary = "\(number) multiplied by \(multiplier) equals \(number * multiplier)"
``````

### Challenge 9: Compute the value

What is the sum of `a` and `b`, minus `c`?

``````let a = 4
let b: Int32 = 100
let c: UInt8 = 12
``````

### Challenge 10: Different precision 𝜋s

What is the numeric difference between `Double.pi` and `Float.pi`?

## Key points

• Type conversion allows you to convert values of one type into another.
• Type conversion is required when using an operator, such as the basic arithmetic operators (`+`, `-`, `*`, `/`), with mixed types.
• Type inference allows you to omit the type when Swift already knows it.
• Unicode is the standard for mapping characters to numbers.
• A single mapping in Unicode is called a code point.
• The `Character` data type stores single characters. The `String` data type stores collections of characters, or strings.
• You can combine strings by using the addition operator.
• You can use string interpolation to build a string in-place.
• You can use tuples to group data into a single data type.
• Tuples can either be unnamed or named. Their elements are accessed with index numbers for unnamed tuples, or programmer given names for named tuples.
• There are many kinds of numeric types with different storage and precision capabilities.
• Type aliases can be used to create a new type that is simply a new name for another type.
• Protocols are how types are organized in Swift. They describe the common operations that multiple types share.

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.