Answer
Core answer
The simplest rule is:
letcreates a constant.varcreates a variable.
With let, you cannot assign a new value later. With var, you can.
The interesting part is that this behaves differently for value types and reference types.
1. Value types: let makes the whole value read-only
Structs, enums, tuples, String, Array, and Dictionary are value types.
When you declare a value type with let, you cannot change any part of it, even if some properties were declared with var.
struct Counter {
var count: Int
}
let fixedCounter = Counter(count: 0)
fixedCounter.count += 1 // ❌ Error
var changingCounter = Counter(count: 0)
changingCounter.count += 1 // ✅ WorksWhy? Because changing a value type means changing the value itself. If it's declared with let, Swift doesn't allow that.
A simple interview rule is:
For value types, let makes the entire value immutable.2. Reference types: let only locks the reference
Classes are reference types.
When you write let user = User(...), user always points to the same object. However, the object itself can still change if it has mutable (var) properties.
final class User {
var name: String
init(name: String) {
self.name = name
}
}
let user = User(name: "Ana")
user.name = "Priya" // ✅ AllowedRun compiles and executes on the server; output shows below.
What you cannot do is make user point to another object.
final class User {
var name: String
init(name: String) {
self.name = name
}
}
let user = User(name: "Ana")
user = User(name: "Priya") // ❌ ErrorA simple interview rule is:
For classes, let locks the reference, not the object.Interview takeaway
Remember these three rules:
letcreates a constant,varcreates a variable.- For value types,
letmakes the whole value immutable. - For reference types,
letprevents changing the reference, but mutable (var) properties can still be modified.