Why are structs in Swift said to be immutable?

To learn more about structs and mutability, I would recommend reading (or re-reading, if it's been a while) the evolution proposal describing the law of exclusivity (SE-0176).

extension Int {
  mutating func assignResultOf(_ function: () -> Int) {
    self = function()  
  }
}

var x = 0

// CONFLICT.  Calling a mutating method on a value type is a write access
// that lasts for the duration of the method.  The read of 'x' in the closure
// is evaluated while the method is executing, which means it overlaps
// the method's formal access to 'x'.  Therefore these accesses conflict.
x.assignResultOf { x + 1 }

Basically, we have a concept of non-instantaneous, mutable accesses to a struct. Accessing a field of the struct is also an access to the entire enclosing struct.

We also have _modify accessors, which are used to implement such non-instantaneous, mutable accesses. We are not limited to get and set operations (kind-of; _modify is not yet a formal language feature, but is used basically everywhere).

We may also one day have "borrow variables" which allow you to extend those access even further.

If the mutating keyword was not enough, all of these other features strongly imply that structs are indeed mutable. The compiler may make copies in some situations when structs are used in particular ways, but rules such as the law of exclusivity are designed explicitly to provide the guarantees that allow for in-place mutation.

2 Likes