Basic types
In the previous lesson, numbers and text went into the boxes. But the boxes on the shelf come in different shapes, and the shape decides what can go into a box.
A box for whole numbers takes no text, and a box for text takes no number. In a program, the shape of a box is called its type. The type tells the compiler what you can do with a value: numbers can be multiplied, words cannot. If you mix them up, it tells you before the program runs.
Let's start with five basic types that almost every program needs. This program has each of them:
let age = 30
let height = 1.75
let isStudent = true
let name = "Anna"
let grade: Character = "A"
print(age, height, isStudent, name, grade) // 30 1.75 true Anna AEach line declares a constant of its own type, and print prints all five values separated by spaces: 30 1.75 true Anna A. Let's go through the types one by one.
Five basic types
Int: whole numbers
Int holds whole numbers with no fractional part: an age, a count, a place in a queue. For example, 30, 0 or -7.
Double: fractional numbers
Double holds numbers with a fractional part: a height, a price, a temperature. In code, the fractional part is always separated by a dot, never a comma: 1.75. Even a whole number of this type prints with a fractional part: 5.0.
Bool: yes or no
Bool holds one of two values: true, "yes, it holds", or false, "no, it does not". Such constants keep the answer to a question: is the person a student, is the sound on.
String: text
String holds text in double quotes, such as "Anna". The quotes mark where the text starts and ends in the code, and print does not print them.
Character: one character
Character holds exactly one character: a letter, a digit or a sign. It is written in the same double quotes as text, so you name the type explicitly: let grade: Character = "A". Without : Character, grade would hold a one-letter string.
Type inference
In the first four lines of the example, no type is written anywhere, yet every constant still has one. Swift picks it on its own from the value to the right of =. This is called type inference. type(of:) lets you see the type it picked:
print(type(of: 5), type(of: 5.0)) // Int Double
print(type(of: "5"), type(of: true)) // String BoolThe inference rule is short:
- a whole number
5givesInt; - a number with a dot
5.0givesDouble; - text in quotes
"5"givesString; trueandfalsegiveBool.
Interviewers like to ask: "How does Swift know the type if you did not write it?" The compiler infers it from the value at declaration, and it never changes. Every name has a type, even though you do not always write it.
Type annotation
Sometimes inference gives a type other than the one you need. A price of 5 is a whole number, but prices can be fractional too, so the box has to be for fractional numbers. Then you state the type yourself: a colon and the type's name after the constant's name. This is called a type annotation:
let price: Double = 5
print(price) // 5.0Let's take the line let price: Double = 5 apart:
let— we declare a constant;price— its name;: Double— the annotation: a box for fractional numbers;= 5— the value, which Swift puts into the box as5.0.
That is why print(price) prints 5.0, not 5. You write an annotation when inference would give the wrong type: Double for a whole number or Character for a single letter. Otherwise you usually leave it out: in let age = 30 the type is clear anyway.
Here the box picture stops working. A real box can be reshaped to fit something else. But the type of a constant or a variable is set once, when it is declared, and it never changes until the program ends—not even for a var.
Common mistake
Text was put into a variable that holds a number:
var year = 2024
year = "next" // ✗error: cannot assign value of type 'String' to type 'Int'var lets you change the value, but not the type. Swift inferred the type Int for year from the number 2024, and a string does not fit into that box. If you need to keep text, make a separate variable for it: var yearText = "next".
Key points
- Every value in Swift has a type; the basic types are
Int,Double,Bool,StringandCharacter. - Swift infers the type from the value:
5is anInt,5.0aDouble,"5"aString. - An annotation states the type explicitly:
let price: Double = 5holds5.0. - A type is set when the name is declared and never changes afterwards, not even for a
var.