# Swift Variables (var) and Constants (let) Explained

Source: https://devdocs10.com/articles/swift/swift-variables-constants  
By Murat Bo · Updated 2026-10-17 · DevDocs10 (https://devdocs10.com)

Swift uses variables and constants to store values in your program. This topic is one of the first things every Swift developer learns, because almost every piece of code depends on naming data, reading it later, and deciding whether that value should be allowed to change. In this article, you will learn what `var` and `let` mean, how to declare them, when to use each one, and how to avoid the most common beginner mistakes.

> **Quick answer:** In Swift, use `var` to create a variable whose value can change, and use `let` to create a constant whose value cannot be reassigned after it is set. In most cases, prefer `let` by default and switch to `var` only when you truly need mutability.

> **Difficulty:** Beginner
>
> **Helpful to know first:** You will understand this better if you already know basic Swift syntax, how to print values, and simple types such as `String`, `Int`, and `Bool`.

## 1. What Is Variables (var) & Constants (let)?

A variable or constant gives a name to a value so your program can use it later. Instead of writing the same literal value everywhere, you store it once and refer to it by name.

- `var` creates a stored value that can be changed later.
- `let` creates a stored value that cannot be reassigned after initialization.
- Both help make code more readable by replacing raw values with meaningful names.
- Swift encourages safe code, so constants are preferred whenever possible.
- The main comparison is simple: `let` means immutable binding, while `var` means mutable binding.

For example, a user's name usually stays the same during a short function, so it can often be declared with `let`. A score in a game changes over time, so it should usually be declared with `var`.

## 2. Why Variables (var) & Constants (let) Matters

Choosing between `var` and `let` affects correctness, readability, and safety.

When you use `let`, Swift protects that value from accidental reassignment. This reduces bugs, especially in longer functions where values pass through several steps. A constant also communicates intent to other developers: this value is meant to stay fixed.

When you use `var`, you allow a value to evolve. This is useful for counters, user input, temporary state, and calculations that happen in stages.

In real projects, using the right one matters because:

- It prevents unintended changes to important values.
- It makes code easier to reason about during debugging.
- It helps the compiler enforce safer patterns.
- It signals whether a value is part of changing state or fixed configuration.

> A helpful rule is: if you are not sure whether a value should change, start with `let`. If Swift later shows that reassignment is necessary, change it to `var`.

## 3. Basic Syntax

The syntax for declaring a variable or constant is simple. You write the keyword, then a name, then optionally a type annotation, and then a value.

### Declaring a constant with let

Use `let` when the value should stay the same after it is assigned.

```swift
let siteName = "DevDocs10"
print(siteName)
```

Output (tested with Swift 6.4):

```text
DevDocs10
```

This creates a constant named `siteName`. Swift infers that its type is `String` from the assigned value.

### Declaring a variable with var

Use `var` when the value needs to change.

```swift
var score = 0
score = 10
print(score)
```

Output (tested with Swift 6.4):

```text
10
```

This works because `score` was declared as a variable, so Swift allows reassignment.

### Adding an explicit type

You can also write the type yourself. This is useful when clarity matters or when the initial value does not make the intended type obvious.

```swift
let maxUsers: Int = 100
var temperature: Double = 21.5
```

Here, the type annotation comes after the name and before the value.

### Declaring first and assigning later

Swift also allows declaration without an immediate value if the type is known and the value will be set before use.

```swift
var username: String
username = "Taylor"
print(username)
```

Output (tested with Swift 6.4):

```text
Taylor
```

This is valid because the variable has a type and gets a value before it is read.

## 4. Step-by-Step Examples

### Example 1: Storing a fixed app name

An app name usually does not change while the program runs, so a constant is a good fit.

```swift
let appName = "WeatherNow"
print("App: \(appName)")
```

Output (tested with Swift 6.4):

```text
App: WeatherNow
```

This example shows a constant used for configuration-style data that should remain unchanged.

### Example 2: Updating a counter

Counters change over time, so they should be variables.

```swift
var pageViews = 0
pageViews += 1
pageViews += 1
print(pageViews)
```

Output (tested with Swift 6.4):

```text
2
```

The value starts at `0` and changes as visits are counted.

### Example 3: Using type annotations for clarity

Sometimes adding the type makes your intent clearer to the reader.

```swift
let pi: Double = 3.14159
var cartItems: Int = 2
print(pi)
print(cartItems)
```

Output (tested with Swift 6.4):

```text
3.14159
2
```

This is especially useful in tutorial code, APIs, and places where inferred types may be less obvious.

### Example 4: Declaring a value and assigning it later

You may know the type before you know the exact value.

```swift
var message: String

message = "Welcome back!"
print(message)
```

Output (tested with Swift 6.4):

```text
Welcome back!
```

This is common when a value depends on later logic, user input, or a function result.

## 5. Practical Use Cases

- Use `let` for fixed configuration values such as app names, API base URLs, and tax rates that should not be reassigned.
- Use `var` for counters, scores, totals, and values that are updated inside loops.
- Use `let` for function-local values that are calculated once and then reused.
- Use `var` for form input, current selections, or state that changes in response to user actions.
- Use `let` to make important values safer when passing them through multiple lines of logic.
- Use `var` when building a value step by step, such as accumulating a total price or building a status message.

## 6. Common Mistakes

### Mistake 1: Trying to reassign a constant

A constant declared with `let` can only be assigned once. After that, Swift does not allow a new value.

**Problem:** This code tries to change a constant after initialization, so Swift reports an error such as `Cannot assign to value: 'name' is a 'let' constant`.

```swift
let name = "Ana"
name = "Mila"
```

**Fix:** Use `var` only if the value is meant to change.

```swift
var name = "Ana"
name = "Mila"
```

The corrected version works because `var` allows reassignment.

### Mistake 2: Declaring without enough type information

Swift needs to know the type of a variable or constant. If you do not provide a value or a type annotation, Swift cannot infer what the storage should hold.

**Problem:** This declaration does not include a value or a type, so Swift cannot infer the intended type and reports an error.

```swift
var total
```

**Fix:** Either assign an initial value or provide an explicit type annotation.

```swift
var total = 0
var price: Double
```

The corrected version works because Swift now knows what type each variable should store.

### Mistake 3: Reading a variable before assigning a value

If you declare a variable with a type but no initial value, you must assign something before using it.

**Problem:** This code attempts to read `greeting` before it has been initialized, which causes a compile-time error.

```swift
var greeting: String
print(greeting)
```

**Fix:** Assign a value before the first read.

```swift
var greeting: String
greeting = "Hello"
print(greeting)
```

Output (tested with Swift 6.4):

```text
Hello
```

The corrected version works because the variable is initialized before it is used.

### Mistake 4: Using var when let communicates intent better

Not every value that *could* be mutable should be mutable. Overusing `var` makes code harder to reason about.

**Problem:** This code marks a fixed value as mutable, which can lead to accidental reassignment later and makes the code less clear.

```swift
var countryCode = "US"
print(countryCode)
```

Output (tested with Swift 6.4):

```text
US
```

**Fix:** Use `let` when the value should stay constant.

```swift
let countryCode = "US"
print(countryCode)
```

Output (tested with Swift 6.4):

```text
US
```

The corrected version communicates more clearly that the value is fixed.

## 7. Best Practices

### Practice 1: Default to let

A common Swift style is to start with `let` and change to `var` only when needed. This makes your intent safer and clearer.

Less preferred:

```swift
var username = "Casey"
```

Preferred:

```swift
let username = "Casey"
```

This practice reduces accidental changes and better documents your code.

### Practice 2: Choose descriptive names

The name of a variable or constant should tell the reader what the value means, not just that a value exists.

Less preferred:

```swift
let x = 30
```

Preferred:

```swift
let maxLoginAttempts = 30
```

Descriptive names make maintenance easier and reduce the need for extra comments.

### Practice 3: Add explicit types when they improve clarity

Swift type inference is powerful, but an explicit type can make code easier to read in APIs, shared code, or educational examples.

Less preferred when the intended type is not obvious:

```swift
let timeout = 5
```

Preferred when you want to show intent clearly:

```swift
let timeoutSeconds: Double = 5.0
```

This helps other developers understand the expected kind of value immediately.

## 8. Limitations and Edge Cases

- A `let` constant cannot be reassigned, but that does not mean every nested piece of data is always deeply immutable in every scenario. The exact behavior depends on the type and whether it exposes mutable internal state.
- Swift must know a variable's type either from the assigned value or from an explicit annotation. A declaration with neither will fail to compile.
- A variable declared without an initial value cannot be used until it has been initialized.
- Type inference is convenient, but sometimes integer and floating-point values can behave differently than beginners expect. For example, `5` is inferred as `Int`, while `5.0` is inferred as `Double`.
- If you see a message like `Cannot assign to value: 'x' is a 'let' constant`, the problem is reassignment, not the original declaration syntax.
- If a value truly needs to change across steps of a calculation, forcing it into `let` will make the code awkward. In those cases, `var` is the correct choice.

## 9. Practical Mini Project

Let’s build a small checkout summary that uses both constants and variables. Constants hold fixed values such as product name and shipping fee. Variables hold values that change, such as quantity and total cost.

```swift
let productName = "Notebook"
let unitPrice: Double = 4.50
let shippingFee: Double = 2.00

var quantity = 2
var subtotal = Double(quantity) * unitPrice
var total = subtotal + shippingFee

print("Product: \(productName)")
print("Quantity: \(quantity)")
print("Subtotal: \(subtotal)")
print("Total: \(total)")

// Customer adds one more notebook
quantity = 3
subtotal = Double(quantity) * unitPrice
total = subtotal + shippingFee

print("Updated quantity: \(quantity)")
print("Updated total: \(total)")
```

Output (tested with Swift 6.4):

```text
Product: Notebook
Quantity: 2
Subtotal: 9.0
Total: 11.0
Updated quantity: 3
Updated total: 15.5
```

This example shows a realistic pattern: fixed values are constants, while values that react to user behavior are variables. That makes the code easier to read and safer to maintain.

## 10. Key Points

- `var` creates a value that can be reassigned later.
- `let` creates a value that cannot be reassigned after initialization.
- Prefer `let` by default and switch to `var` only when change is required.
- Swift can often infer types, but explicit annotations are useful when they improve clarity.
- A variable declared without an initial value must be assigned before it is read.
- The error `Cannot assign to value: is a 'let' constant` means you tried to change a constant.

## 11. Practice Exercise

Create a small program for tracking a user's reading progress.

- Declare a constant for the book title.
- Declare a constant for the total number of pages.
- Declare a variable for the current page and set it to an initial value.
- Update the current page after the user reads more pages.
- Print the book title, total pages, current page, and remaining pages.

**Expected output:** The program should show fixed book information and an updated reading position after the page value changes.

**Hint:** Use `let` for values that do not change and `var` for the page number that updates.

```swift
let bookTitle = "Swift Basics"
let totalPages = 250

var currentPage = 40
print("Book: \(bookTitle)")
print("Total pages: \(totalPages)")
print("Current page: \(currentPage)")
print("Remaining pages: \(totalPages - currentPage)")

currentPage = 85
print("Updated current page: \(currentPage)")
print("Updated remaining pages: \(totalPages - currentPage)")
```

Output (tested with Swift 6.4):

```text
Book: Swift Basics
Total pages: 250
Current page: 40
Remaining pages: 210
Updated current page: 85
Updated remaining pages: 165
```

## 12. Final Summary

Variables and constants are foundational in Swift because they control how your program stores and manages data. The key distinction is simple: use `let` for values that should not change, and use `var` for values that must change over time. That one decision improves safety, readability, and correctness throughout your code.

In this article, you learned the core syntax, saw how type inference and type annotations work, explored practical examples, fixed common errors, and applied the concept in a small mini project. If you want to continue building your Swift basics, a strong next step is learning Swift data types such as `String`, `Int`, `Double`, and `Bool`, because variables and constants become much more useful once you understand the kinds of values they can store.
