Swift gives you two ways to bundle data together: struct and class. They look almost identical on the page:
struct PlayerStruct {
var score = 0
}
class PlayerClass {
var score = 0
}
The difference is what happens on assignment:
- A
structis a value type:var b = amakes a full, independent COPY. Changeb, andadoesn't care. - A
classis a reference type:let b = acopies only a reference. Both names point at ONE shared object — change it through either name and both see it.
Same syntax, opposite behavior — and it decides whether a change in one corner of your program silently shows up in another.
The trap:
Because a struct copy is a real value of its own, mutating it through a let constant is forbidden. This looks harmless:
let copy = original // original is a struct
copy.score = 100
...and the compiler refuses it:
trap.swift:6:6: error: cannot assign to property: 'copy' is a 'let' constant
4 | let original = Player()
5 | let copy = original
| `- note: change 'let' to 'var' to make it mutable
6 | copy.score = 100
| `- error: cannot assign to property: 'copy' is a 'let' constant
Do what the note says: declare the copy with var. The flip side surprises people just as much: a let constant holding a class instance DOES allow copy.score = 100 — only the reference is constant, not the object it points to.
Assignment
Follow the Coding Tutorial and see both behaviors with your own eyes:
- define
PlayerStruct(struct) andPlayerClass(class), each withvar score = 0, - make
structCopyfromstructOriginal, set the copy's score to100, print both, - make
classCopyfromclassOriginal, set its score to100, print both.
The exact expected output is:
struct original = 0
struct copy = 100
class original = 100
class copy = 100
Hint
Only structCopy needs var — you mutate the struct value itself. The class bindings can all stay let, because you never change what they point at, only the object's property.
Free plan: 30 tutor messages. Premium is unlimited.