Changing property of regular struct(not copy-on-write) doesn’t make copy

class A {
    var aProperty:String = ""
    let bb = "hello"
}

struct B {
    let a: A
    var bb = "hello"
}

var b = B(a: A()) {
    didSet {
        print(">>>> b is set!")
    }
}
print("b: ", address(of: &b)) //"b:  0x105af48d0\n"
b.a.aProperty = "change"
print("b: ", address(of: &b)) //"b:  0x105af48d0\n"
b.bb = "change" //">>>> b is set!"
print("b: ", address(of: &b)) //"b:  0x105af48d0\n"

Changing property of regular struct(not copy-on-write) doesn’t make copy. It mutates the value. It assigns a new value to it, so didSet is called.
https://chris.eidhof.nl/post/structs-and-mutation-in-swift/

Mutating a struct variable is semantically the same as assigning a new value to it.

didSet still needs to get triggered.

With regular structs, the compiler will mutate the value in place, and not actually make a copy. With copy-on-write structs (which we’ll discuss later), this works differently.

For arrays, the memory address changes when new element is added. So for copy-on-write structs, mutating property makes copy.

var array2: [Int] = array1
print("array2:", address(of: array2)) // "array2: 0x600000885e20\n"

array2.append(5) // COW
print("array2:", address(of: array2)) // "array2: 0x6000039b1220\n"