You can find Part 2 here.
In Part 2 you learned how to declare constants and variables. When we declared
let pi = 3.14159 or
let email = "firstname.lastname@example.org", we didn't seem to care too much that one is a number (pi) and the other is text (an email address). However, you probably noticed that pi was declared without quotes while the email address was declared with quotes. This is because numbers and text are different types of data, and Swift cares very much about this distinction.
We also saw when discussing constants and variables why the self-imposed constraints of constant values are powerful. In this tutorial we'll learn about data types, why Swift is so rigid about the types we use, and why that's another example of how a constraint can make our code safer and easier to understand.
Open your "HelloSwift" Xcode project. You should have the following:
let pi = 3.14159 let email = "email@example.com" let four = 2 + 2 var printedLines = 0 print(pi) print(email) print(four) printedLines = 3 print(printedLines) printedLines = 4
Try changing the value of
printedLines to "Hello":
printedLines = "Hello"
Xcode will give you the following error:
Cannot assign value of type 'String' to type 'Int'. What's happening here? Swift recognized that
printedLines is an integer value. We are using it to track how many times we have printed something to the Console. When we try to change the value from the integer
4 to the text
"Hello", that doesn't make much sense.
To see this even more clearly, imagine that we were able to change the value of
"Hello". Then we continue on, printing another value to the console and incrementing
printedLines by 1 as follows:
printedLines = printedLines + 1
The above line is a very reasonable thing to do, but what's
"Hello" + 1? This is why the error you got when trying to set
"Hello" is actually powerful, not limiting. This feature of Swift is called Type Safety, and it prevents us from writing code that would lead to undefined behavior like
"Hello" + 1.
Not all programming languages impose this constraint, and some developers argue that languages without type safety offer greater flexibility and control. My view is that type safety is a very good thing that prevents errors and makes code easier to read and understand, both for the original author and the other developers they work with. Swift also has other features, like protocols and generics, which add the flexibility and control type unsafe languages offer while still preventing the programmer from making errors. I'll write more about protocols and generics later!
Now that we've talked about why types are important, let's look at some actual types!
In computer science, the term for a piece of text is a "string". We'll use this term from now on to refer to text, whether it's an email address, name, paragraph, or really anything that we would represent with alphanumeric characters and punctuation. Unsurprisingly, the data type for a string in Swift is
String. You've already seen how a String can be declared in Swift:
let email = "firstname.lastname@example.org"
However, this is shorthand (more on that below). We specify the type of a constant or variable in Swift with a colon as follows:
let email: String = "email@example.com"
Notice the colon comes right after the name of the constant, followed by a space, then the type. This is not enforced by the language, but is done by convention.
In Part 1, we printed the String value "Hello, World!" to the Console. Let's declare that as a constant on a new line in our "HelloSwift" project now.
let hello: String = "Hello, World!"
Int & Double
Integer values in Swift are represented with the
Int type, while decimal numbers are usually declared with the
Double type (there are other types that can be used to represent both integers and decimal numbers, but these are by far the most common). We've already declared each of these types:
let pi = 3.14159 var printedLines = 1
To specify the types explicitly, we only need to change the above to the following:
let pi: Double = 3.14159 var printedLines: Int = 1
Int values are both numbers, you might wonder why we need separate types. After all,
3.14159 + 1 makes a lot more sense than
"Hello" + 1, right? Yes, but in this case we have a variable
printedLines that tracks the number of times we print to the Console, and we can't print to the Console 4.14159 times. Therefore, it's helpful to treat integers and doubles as different data types.
Back in Xcode, try the following:
printedLines = printedLines + pi
Sure enough, you get an error:
Binary operator '+' cannot be applied to operands of type 'Int' and 'Double'. Swift is once again preventing us from making a mistake.
A Boolean is a special data type that can only have the value
false. It is particularly useful in conditional logic ("if this, then that"). The Swift data type for booleans is called
Bool. We can declare a
Bool as follows:
let isAdult: Bool = false
We've declared a constant that's always false, which is not very helpful. Let's consider a more realistic example. Add the following at the bottom of "main.swift" in Xcode:
let age: Int = 32 let isAdult = age >= 18 print(isAdult)
Here we've declared an integer value to represent a person's age and set
isAdult to be
age is greater than or equal to
18, otherwise false. The Console should print
As we've seen, we can declare constants and variables without explicitly specifying the data type. When we tried to set
"Hello" and got the error,
Cannot assign value of type 'String' to type 'Int', we had not yet specified
printedLines as an integer value.
We got the error anyway because Swift tries to infer the type of the value you declare when you don't explicitly specify a type. If you use quotes, it knows you are declaring a
String. If you set declare
printedLines with a value of
0, it infers that you are declaring an integer. When you declare
3.14159, Swift infers the type as
Double. Finally, when you declare a value as
false (or an expression that evaluates to either like
age >= 18), Swift knows the type must be
Now that you know about type inference, you do not have to specify the type when declaring a constant or variable. However, you can use your knowledge of type inference to be clear about what you want, or to explicitly specify a type when you need to. For example, if you wanted to treat
printedLines as a
Double, you could do one of the following.
var printedLines = 0.0
var printedLines: Double = 0
In the first example, we are telling Swift we want a
Double by adding a decimal place. In the second, we are explicitly specifying the type as
Double because we know Swift will otherwise infer the type as
Type inference allows our code to be more concise. While using type inference may seem to make code more difficult to read at first, as you get more comfortable with types I think you'll find you internalize the inference rules. Code then becomes easier to read, both because it's shorter and because you only see explicitly declared types when they are necessary.
You should now be able to answer these questions:
In this tutorial you learned how to specify types and the benefits of type safety and type inference. You also learned about four of the built-in Swift types,
Bool. There are many more that we'll cover later, and you can also create your own! For example, if you want to represent a book, user, country, network, game, or countless other things and ideas in code, you can declare a custom type. I'll cover that in a future post, but first we'll learn about another basic building block of programming, Functions.