Answer
Core answer
In Swift, let declares a constant binding and var declares a mutable binding. The simplest interview answer is: with let, you cannot reassign the name to a new value later; with var, you can.
That basic rule is correct, but strong candidates go one step further: the effect feels different for value types and reference types. With value types, let makes the stored value itself immutable. With reference types, let makes the reference immutable, but the object that reference points to may still contain mutable var properties.
1. Value types: let makes the value immutable
Structs, enums, tuples, String, Array, and Dictionary are all value types in Swift. When you declare a value type with let, Swift treats the entire value as immutable, even if some of its stored properties were declared with var.
struct Counter {
var count: Int
}
let fixedCounter = Counter(count: 0)
fixedCounter.count += 1 // ❌ Compile-time error!
var changingCounter = Counter(count: 0)
changingCounter.count += 1 // ✅ Now it works!Why? Because mutating a value type means replacing its stored value with a new version. If the binding itself is a constant, Swift does not allow that mutation.
This is why you should say in an interview: for value types, let usually means the whole value is frozen.
2. Reference types: let freezes the reference, not the whole object
Classes are reference types. A class instance lives separately from the variable or constant that points to it. When you write let user = User(...), the constant is the reference. Swift prevents you from making user point to a different instance, but it does not automatically make every property inside that instance immutable.
final class User {
var name: String
init(name: String) {
self.name = name
}
}
let user = User(name: "Ana")
user.name = "Priya" // ✅ Allowed because the instance property is mutable
print(user.name)Run compiles and executes on the server; output shows below.
What Swift rejects here is reassignment of the reference itself:
final class User {
var name: String
init(name: String) {
self.name = name
}
}
let user = User(name: "Ana")
user = User(name: "Priya") // ❌ Compile-time error!That is the key distinction interviewers want: let on a class instance does not mean deep immutability. It means the reference cannot be changed to point somewhere else.
Interview angle
Walk the answer in this order: let means no reassignment -> var means reassignment is allowed -> for a struct, let usually freezes the whole value -> for a class, let freezes only the reference -> mutable properties on the instance can still change unless the type itself is designed to be immutable.