Swift Variables (var) and Constants (let) Explained
Swift uses variables and constants to store values in your program. Understanding when to use var and when to use let is one of the first important Swift skills, because it affects safety, readability, and whether your code can change data later.
Quick answer: Use var when a value needs to change, and use let when it should stay the same after it is set. In Swift, let is preferred by default because it makes code safer and prevents accidental changes.
Difficulty: Beginner
Before this: Basic Swift syntax, printing values, simple data types like strings and integers
1. What Is Variables (var) & Constants (let)?
A variable or constant gives a name to a value so you can use that value later in your code. In Swift, both store data, but they differ in whether the stored value can change.
- var creates a variable, which means the value can be changed later.
- let creates a constant, which means the value cannot be reassigned after initialization.
- Both can store values such as strings, numbers, booleans, arrays, and custom types.
- Swift encourages constants by default because immutable values reduce bugs.
- The most common beginner comparison is let vs var: same purpose, different mutability.
If you know a value should not change, using let communicates that intent clearly. If the value must be updated during program execution, use var.
2. Why Variables (var) & Constants (let) Matters
Almost every Swift program stores values: a user's name, a score, a setting, a total price, or whether a feature is enabled. Choosing the right keyword matters because it affects how safely that data is handled.
Using let where possible helps you:
- Prevent accidental reassignment
- Make code easier to understand
- Express intent clearly to other developers
- Reduce mutation-related bugs
Using var is appropriate when:
- A counter needs to increase
- User input can replace an earlier value
- A collection needs to add or remove items
- A state value changes over time
Warning: Beginners often overuse var. In Swift, the safer habit is to start with let and switch to var only when mutation is actually required.
3. Basic Syntax or Core Idea
The basic syntax is simple: write let or var, then a name, then a value.
Declaring a constant
Use a constant for values that should stay the same after assignment.
let siteName = "DevDocs10"
let maxLoginAttempts = 3
Here, siteName and maxLoginAttempts cannot be assigned new values later.
Declaring a variable
Use a variable when the value must change.
var score = 0
score = 10
This works because score was declared with var.
Type inference and explicit types
Swift usually infers the type from the assigned value, but you can also write the type explicitly.
let username = "Taylor"
let age: Int = 25
var price: Double = 19.99
Swift infers username as a String. The types for age and price are written explicitly.
Declaring first, assigning later
You can declare a variable or constant before assigning a value, but a constant can only be assigned once.
var city: String
city = "London"
let country: String
country = "UK"
This is valid because each value is initialized before use. The constant country still cannot be assigned a second time.
4. Step-by-Step Examples
Example 1: Storing a user's name
If a value will not change during execution, a constant is the best fit.
let userName = "Ava"
print("Welcome, \(userName)!")
This example uses let because the user's name is treated as fixed for this small program.
Example 2: Updating a game score
Scores often change as the program runs, so a variable is appropriate.
var gameScore = 0
gameScore = gameScore + 50
gameScore = gameScore + 25
print(gameScore)
The value starts at 0 and changes twice, so var is required.
Example 3: Working with an array
With collections, mutability matters. A variable array can be changed, while a constant array cannot be structurally modified.
var tasks = ["Write code", "Test app"]
tasks.append("Fix bugs")
print(tasks)
This works because the array is stored in a var. If it were stored in a let, appending would fail.
Example 4: Explicit type for future changes
Sometimes you want to declare a value with a specific type because it will be assigned later.
var temperature: Double
temperature = 21.5
print(temperature)
The explicit type tells Swift exactly what kind of value temperature will hold.
5. Practical Use Cases
- Use let for configuration values such as API base URLs, app names, and maximum limits that should not change.
- Use var for counters, timers, progress values, and totals that update over time.
- Use let for values returned from a calculation when you only need the result, not future reassignment.
- Use var for form data or user input that may be edited before submission.
- Use let for fixed function results inside a scope to make later code easier to reason about.
- Use var for arrays and dictionaries that need items added, removed, or replaced.
6. Common Mistakes
This topic causes several common beginner errors, especially when switching between mutable and immutable values.
Mistake 1: Trying to reassign a constant
Once a constant is initialized, it cannot receive a new value.
Warning: Bad code:
let language = "Swift"
language = "Kotlin"
This causes an error similar to Cannot assign to value: 'language' is a 'let' constant.
Use a variable if the value needs to change.
var language = "Swift"
language = "Kotlin"
The fix is not to avoid constants, but to choose the correct one for the job.
Mistake 2: Trying to mutate a collection stored in a constant
A constant array or dictionary cannot be structurally changed.
Warning: Bad code:
let numbers = [1, 2, 3]
numbers.append(4)
This can produce an error like Cannot use mutating member on immutable value: 'numbers' is a 'let' constant.
Store the collection in a variable if you need to mutate it.
var numbers = [1, 2, 3]
numbers.append(4)
The collection itself is now mutable, so appending works.
Mistake 3: Declaring without enough type information
If you declare a name without assigning a value, Swift needs an explicit type.
Warning: Bad code:
var total
This is invalid because Swift cannot infer the type.
Declare the type if you will assign later.
var total: Int
total = 100
This gives Swift the information it needs.
Mistake 4: Using var when let is better
This is not always a compiler error, but it is a common design mistake.
Warning: Less safe code:
var taxRate = 0.2
If the tax rate should not change in this context, a constant is clearer.
let taxRate = 0.2
This communicates intent and protects against accidental reassignment.
7. Best Practices
Prefer let by default
Start with let. Change to var only when the program truly needs mutation.
let appTitle = "Task Tracker"
This makes your code safer and easier to follow because other developers know the value will not change.
Use clear, descriptive names
Variables and constants should explain what they store.
var currentPage = 1
let maximumPageCount = 10
These names are much clearer than short, vague names like x or n.
Add explicit types when clarity matters
Type inference is useful, but explicit types can make important code clearer.
let timeoutSeconds: Double = 5.0
This avoids ambiguity and helps readers understand the intended data type immediately.
Limit mutation to the smallest possible scope
If a value changes only inside a short block of logic, keep that mutation local.
func calculateTotal() -> Int {
var total = 0
total += 20
total += 30
return total
}
This keeps the changing value isolated and returns a stable result.
8. Limitations and Edge Cases
- A let constant cannot be reassigned, but that does not always mean every value inside it is deeply immutable in all contexts. For value types like arrays, structural mutation is blocked. For reference types, the reference may be constant while the object's internal state can still change.
- Swift requires initialization before use. Declaring a variable without assigning a value means you must give an explicit type and assign before reading it.
- Type inference is convenient, but it can sometimes infer a type you did not expect, especially with numeric literals.
- Constants improve safety, but you should not force everything into let if the program genuinely needs state changes.
- If code seems "not working" after changing var to let, check whether you are calling mutating methods like append, removeAll, or direct reassignment.
9. let vs var in Swift
This comparison is central to the topic, because both keywords store values but communicate different intent.
| Keyword | Meaning | Can value change? | Common use |
|---|---|---|---|
| let | Constant | No reassignment | Fixed settings, final results, stable values |
| var | Variable | Yes | Counters, editable input, changing state |
In practice:
- Choose let when you know the value should stay fixed after setup.
- Choose var when reassignment or mutation is part of the logic.
- If you are unsure, start with let. The compiler will quickly show you when mutation is needed.
A useful Swift habit is: make immutability the default, not the exception.
10. Practical Mini Project
This small example tracks a shopping cart total, tax rate, and item count. It shows when fixed values should use constants and when changing values should use variables.
let storeName = "Corner Shop"
let taxRate: Double = 0.2
var itemCount = 0
var subtotal: Double = 0.0
itemCount += 1
subtotal += 12.50
itemCount += 1
subtotal += 7.25
let taxAmount = subtotal * taxRate
let finalTotal = subtotal + taxAmount
print("Store: \(storeName)")
print("Items: \(itemCount)")
print("Subtotal: \(subtotal)")
print("Tax: \(taxAmount)")
print("Final total: \(finalTotal)")
In this example, storeName and taxRate are constants because they do not change. itemCount and subtotal are variables because they update as items are added. The calculated results taxAmount and finalTotal use constants because they are final values after calculation.
11. Key Points
- var creates a mutable value that can change later.
- let creates an immutable value that cannot be reassigned after initialization.
- Swift prefers constants by default because they improve safety and clarity.
- Type inference usually determines the value's type automatically.
- If no initial value is given, you must provide an explicit type.
- Mutating methods on collections require the collection to be stored in a var.
- Common errors include trying to reassign a constant or mutate a constant collection.
12. Practice Exercise
Create a small Swift program that stores a student's name, current grade, and completed lessons. The student's name should never change. The grade and completed lesson count should update during the program.
- Store the student's name as a constant.
- Store the grade as a variable starting at 75.
- Store completed lessons as a variable starting at 3.
- Increase the grade by 5.
- Increase completed lessons by 2.
- Print all final values.
Expected output: The printed result should show the fixed student name and the updated grade and lesson count.
Hint: Use let for the name and var for values that change.
let studentName = "Mia"
var grade = 75
var completedLessons = 3
grade += 5
completedLessons += 2
print("Student: \(studentName)")
print("Grade: \(grade)")
print("Completed lessons: \(completedLessons)")
13. Final Summary
Swift variables and constants are simple to write, but choosing between var and let has a big effect on code quality. Variables are for values that must change, while constants are for values that should remain stable after they are set.
You also saw how Swift infers types, when explicit types are useful, how collection mutation depends on mutability, and which compiler errors appear when constants are used incorrectly. A strong Swift habit is to write let first, then switch to var only when your logic requires mutation.
A good next step is to learn Swift data types in more detail, especially strings, numbers, arrays, and optionals, because variables and constants are how you store and work with all of them.