Skip to main content

Learn About Constants, Variables, and Data Types

Learning Objectives

After completing this unit, you’ll be able to:

  • Represent numbers, strings, and Boolean values using native Swift types.
  • Identify when to use a constant and when to use a variable.
  • Assign values to constants and variables.
  • Explain how type inference helps you write clean code.
  • Explain how type safety helps you write safe code.

Building apps, and programming in general, is largely about working with data. As a developer, you'll need to understand how to handle and store data using clearly defined types. Types are like blueprints for working with data.

In this unit, you'll learn how constants and variables help name pieces of data so they can be used later in your program. You'll learn how to define constants for values that don't change, and how to define variables for values that do change.

You'll also learn about types. Different types can be used and stored in constants or variables. You'll learn what types are included in Swift and how Swift types can help you write better code.

Constants

When you want to name a value that won't change during the lifetime of the program, use a constant.

You define constants in Swift using the let keyword.

let name = "John"

The code above creates a new constant called name and assigns the value John to the constant. If you want to access that value in later lines of code, you can use name to reference the constant directly. This quick reference is especially helpful when you have one value that you use many times in a program.

let name = "John"
print(name)

This code would print John to the console.

Because name is a constant, you can't give it a new value after assigning it. For example, the following code won't compile.

let name = "John"
name = "James"

Variables

When you want to name a value that may change during the lifetime of the app, use a variable.

You define variables using the var keyword.

var age = 29
print(age)

The code above would print 29 to the console.

Because age is a variable, you can assign a new value in later lines of code. The following code compiles with no errors.

var age = 29
age = 30
print(age)

This code would print 30 to the console.

You can assign constants and variables from other constants and variables. This functionality is useful when you want to copy a value to one or more other variables.

let defaultScore = 100
var playerOneScore = defaultScore
var playerTwoScore = defaultScore
print(playerOneScore)
print(playerTwoScore)
playerOneScore = 200
print(playerOneScore)

The console would read as follows:

100
100
200

Constant or Variable?

You just learned to use a constant when the value won't change and a variable when the value might change.

But there's a nuance here that's worth learning. Even though certain values might be variable, you can represent them with a constant because they won't change during the lifetime of a single execution of the code.

Imagine you're calculating information about the distance traveled on a trip. The program can be reused to track many trips over time, but it only tracks one trip at a time. How would you represent the following data in your code?

  1. Starting location. This is a GPS coordinate of where you started your trip. Once you begin tracking a trip in your program, the location won't change. You represent this value with a constant.
  2. Destination. This GPS coordinate is where you want to arrive. Your app can be used for many destinations, so you may think this would be represented with a variable. But once your program begins tracking a trip, the destination won't change. You represent this value with a constant.
  3. Current location. The GPS coordinate of your current location will change whenever you move. So represent this value with a variable.
  4. Distance traveled. How far have you traveled from your starting point? This value changes as you move. You represent it with another variable.
  5. Remaining distance. How far must you travel to arrive at your destination? The remaining distance changes as you move. You represent this value with a variable.

Constants and variables perform very similar jobs. You may think it would be easier to use variables for everything and ignore constants altogether. Technically, your code could work this way. So why should you use constants at all?

First, if you set a value to a constant, the compiler understands that value should never be changed. This means you won't be able to build or run your program if you try to change the constant's value. In this way, the compiler enforces safety.

Second, there are special optimizations that the compiler can make for constant values. When you use constants for values that won't change, the compiler can make low-level assumptions about how to store the value. These adjustments allow your program to execute faster.

Third, this process is the idiomatic way to do things in Swift.

As you learn more about building software, you'll come to appreciate best practices for consistently writing clean, readable code. This is especially important when working on a team with other developers. You'll also discover that following best practices will make it easier for you to remember what your code does, especially when you want to make changes later on.

If you want to be a great developer, follow shared patterns and conventions. This module guides you toward the best practices for writing Swift.

Naming Constants and Variables

There are rules for naming constants or variables. The compiler enforces the rules, so you won't be able to build and run your program if you break them. Here are the rules:

  1. Names can't contain mathematical symbols.
  2. Names can't contain spaces.
  3. Names can't begin with a number.

Other than these three rules, you can name a constant or variable whatever you like.

let π = 3.14159
let 一百 = 100
let 🎲 = 6
let mañana = "Tomorrow"
let anzahlDerBücher = 15 //numberOfBooks

In addition to the rules, there are some important best practices for naming constants and variables:

  1. Constant and variable names should be clear and descriptive, so you can easily understand the code when you come back to it later. For example, firstName is better than n and restaurantsNearCurrentCity is better than nearby.
  2. To be clear and descriptive, you should often use multiple words in a name. When you put two or more words together, the convention is to use camel case, which means that you lowercase the first letter in the name and then capitalize the first letter of each new word. You've probably noticed examples of this already: defaultScore is the camel case treatment for the combination of default and score. Camel case is easier to read. For example, defaultScore is clearer than defaultscore and restaurauntsNearCurrentCity is clearer than restaurantsnearcurrentcity.
Note

Note

Did you notice that the translation for anzahlDerBücher was written off to the side? As code becomes more complex, you might find it useful to leave little notes for yourself, as well as for other developers who might read your code. You create these comments by placing two forward slashes in front of the text. When your code is compiled, the comments will be ignored, so write as many as you find helpful.

// Setting pi to a rough estimate
let π = 3.14

If you need multiple lines for your comment, you can also place as much text as you'd like between /* and */, and it will be ignored by the Swift compiler.

/* The digits of pi are infinite,
so instead I chose a close approximation.*/
let π = 3.14

Comments are most frequently used to explain difficult sections of code, provide copyright information at the top of a file, and provide dating information (when the file was created and/or modified).

Types

Each Swift type comes with properties and functions that may be helpful when working with constants or variables of that type. A property represents information about an object, and a function performs some sort of action with the object.

Consider a simple Person type defined here:

struct Person {
 var firstName: String
 var lastName: String
 func sayHello() {
  print("Hello there! My name is \(firstName) \(lastName).")
 }
}

You probably aren't familiar with all the syntax in the code block above. That's OK. It's called a type definition, and it defines the properties and functions of a Person type.

You can think about a type definition as a blueprint for how objects should look and function. This example describes how objects of the type Person should look and perform.

By reading it, you can see there are two String values, firstName and lastName. These are called properties, which store information about the person. You also see sayHello(), which is a function and defines an action for the person.

Whenever you create a new variable, you're creating an instance of a type. Consider the following code:

let aPerson = Person(firstName: "Jacob", lastName: "Edwards")
let anotherPerson = Person(firstName: "Candace", lastName: "Salinas")
aPerson.sayHello()
anotherPerson.sayHello()

This will print the following:

Hello there! My name is Jacob Edwards.
Hello there! My name is Candace Salinas.

This code creates two instances of the Person type. One instance represents a Person named Jacob Edwards, and the other instance represents a person named Candace Salinas.

Swift comes with many predefined types that make it easier to write clean code. Whether your program needs to include numbers, strings, or Boolean (true/false) values, you can use types to represent a specific kind of information.

Here are a few of the most common types in Swift:

Type Name
Symbol
Purpose
Example
Integer
Int

Represents whole numbers, or integers
4

Double
Double
Represents numbers requiring decimal points
13.45
Boolean
Bool
Represents true or false values
true
String
String
Represents text
“Once upon a time …”

Swift also supports collection types, which group instances into a single variable. One collection type is called an Array, which stores an ordered list of objects. Another collection type is called a Dictionary, which has keys that help you look up specific values. You can use collections to store multiple objects in a single constant or variable.

The Swift standard library includes all of the types above, so they're always available to you.

In addition, you can define your own types in Swift using the same structure you saw earlier in the Person example.

Type Safety

Swift is considered a type-safe language. Type-safe languages encourage or require you to be clear about the types of values your code can work with. For example, if you have a function that expects an Int, you can't pass it a Double or a String.

When compiling your code, Swift performs type checks on all of your constants and variables, and flags any mismatched types as errors. If you mismatch types, you won't be able to run your program.

let playerName = "Julian"
var playerScore = 1000
var gameOver = false
playerScore = playerName
// Will be flagged for mismatched types, will not compile.

Because type safety requires you to be careful about which types you work with, the example above is an obvious mismatch. Assigning a String value to an Int variable doesn't make sense. When you access playerScore, you know you want a score value represented by a number and not by text.

Type safety also applies to values that represent data that may seem compatible. For example, the compiler recognizes Int and Double as completely different types, even though they both represent numbers.

var wholeNumber = 30
var numberWithDecimals = 17.5
wholeNumber = numberWithDecimals
// Will be flagged for mismatched types, will not compile.

In the case above, both variables are numbers, but wholeNumber will be an Int and numberWithDecimals will be a Double. In Swift, you can't assign a value of one type to a variable of another type.

When working with numbers, you may find that you need to assign a very large value to a variable or constant. This can be difficult to read, since it is hard to see how many zeros there are in 1000000000. Fortunately, Swift allows you to put underscores in your numbers as a way of formatting for easier reading.

var largeUglyNumber = 1000000000
var largePrettyNumber = 1_000_000_000

Type Inference

You may have noticed that you don't have to specify the type of value when you declare a constant or variable. This is called type inference. Swift uses type inference to make assumptions about the type based on the value assigned to the constant or variable.

let cityName = "San Francisco"
// "San Francisco" is obviously a `String`, so the compiler
// automatically assigns the type of cityName to a `String`.
let pi = 3.1415927
// 3.1415927 is a number with decimal points, so the compiler
// automatically assigns the type `pi` to a `Double`.

Once you assign a value to a constant or variable, the type is set and can't be changed. This is true even for variables. The value of a variable may change, but not its type.

There may be cases when it's useful, or even required, to explicitly specify the type of a constant or variable. This is called a type annotation. To specify a type, add a colon (:), a space, and the type name following the constant or variable name.

let cityName: String = "San Francisco"
let pi: Double = 3.1415927

You can use a type annotation with different number types. The Swift compiler will adjust the value to match the type.

let number: Double = 3
print(number)

This will print 3.0.

There are three common cases for using a type annotation:

1. When you create a constant or variable but haven't yet assigned it a value.

let firstName: String
//...
firstName = "Layne"

2. When you create a constant or variable that could be inferred as more than one type.

let middleInitial: Character = "J"
// "J" would be inferred as a `String`, but we want a `Character`
var remainingDistance: Float = 30
// `30` would be inferred as an `Int`, but the variable should support decimal numbers for accuracy as the number decreases.

3. When you want to write your own type definition.

struct Car {
 var make: String
 var model: String
 var year: Int
}

Required Values

Whenever you define a constant or variable, you must either specify a type using a type annotation or assign it a value that the compiler can use to infer the type.

var x
// This would result in an error.

Even when you use a type annotation, your code can't work with a constant or variable if you haven't yet assigned it a value.

var x: Int
print(x)
// This would result in an error.

Once the value is assigned, the constant or variable becomes available.

var x: Int
x = 10
print(x)

Complete the Lab

Ready to get hands-on experience with Swift? Practice what you learned with the exercises in Lab - Constants and Variables.playground.

Resources

Keep learning for
free!
Sign up for an account to continue.
What’s in it for you?
  • Get personalized recommendations for your career goals
  • Practice your skills with hands-on challenges and quizzes
  • Track and share your progress with employers
  • Connect to mentorship and career opportunities