Array<Element> holds an ordered, possibly-duplicate-containing list; Set<Element> holds unordered, guaranteed-unique elements (requiring Hashable); Dictionary<Key, Value> maps unique keys to values. All three are structs, inheriting exactly the same value-type, copy-on-assignment semantics covered in structs-and-classes — assigning an array to a new variable produces a genuinely independent copy, not a shared reference. Internally, Swift optimizes this with copy-on-write: the actual underlying storage is only duplicated the moment one of the two copies is mutated, not on every assignment — an implementation detail that keeps assignment cheap while preserving the value-type guarantee completely.
Arrays: value semantics in action
array2 is a genuinely independent copy — modifying it has zero effect on array1, exactly the same guarantee a custom struct gets, since Array itself IS a struct.
var array1 = [1, 2, 3]
var array2 = array1 // COPIES array1 — array2 is independent
array2.append(4)
print(array1) // [1, 2, 3] — completely unaffected by the change to array2
print(array2) // [1, 2, 3, 4]Set: unique, unordered elements
Adding a duplicate value simply has no effect — Set silently enforces uniqueness, and set operations like intersection are built-in, genuine mathematical set operations.
var colors: Set = ["red", "green", "blue"]
colors.insert("red") // no effect — "red" already exists in the set
let warm: Set = ["red", "orange", "yellow"]
print(colors.intersection(warm)) // ["red"] -- Swift prints a Set with square brackets, same notation as Array, not curly bracesDictionary: key-value pairs
Subscripting a Dictionary returns an Optional (Value?), since the key genuinely might not exist — nil coalescing (??) provides a clean fallback for the missing case.
var ages: [String: Int] = ["Alice": 30, "Bob": 25]
ages["Charlie"] = 35 // adds a new key-value pair
let aliceAge = ages["Alice"] // Optional(30) — subscripting returns Int?
let daveAge = ages["Dave"] ?? 0 // 0 — key doesn't exist, fallback used