swift 类 是否在分配期间通过副本传递的结构内部?
Are swift classes inside struct passed by copy during assignment?
如果我在 swift 中有一个带有 class 属性的结构并且我复制了结构对象,class 属性是通过引用复制还是传递?
参考通过。你可以测试一下。声明:
class A{}
struct B { let a = A()}
然后:
let b = B()
print("A = \(unsafeAddressOf(b.a))")//0x0000600000019450
let b_copy = b
print("A = \(unsafeAddressOf(b_copy.a))")//0x0000600000019450
一个结构的所有属性被复制(就像你分配(=
)旧结构的每个属性到相应的属性 的新结构)复制结构时,无论类型如何。
当您说 "class attribute" 时,我假设您指的是引用类型的变量。 (与 class 同名的类型表示指向该 class 对象的引用的引用类型。)复制引用类型(引用)的值会产生另一个指向同一个对象。请注意 "objects" 不是 Swift 中的值——没有 "object types" —— 相反,对象总是通过指向它们的引用来操作。
我在swift5测试了上面的实验:
让我们看看结果:
class A {
var id: Int
init(id: Int) {
self.id = id
}
}
struct B {
var grade: Int
var a: A
}
根据结果进行实验:
var a = A(id: 1)
var a_copy = a
var b1 = B(grade: 2, a: a)
var copy_b1 = b1
print(b1.a.id)
b1.a.id = 5
print(copy_b1.a.id)
print(b1.grade)
b1.grade = 3
print(copy_b1.grade)
输出:
1
5 // call by reference, same result
2
2 // call by value, no change in result
结论:
当我们创建它的另一个对象时,struct 会复制。它复制其结构 属性 (按值调用)但引用 class 属性 的相同实例(按引用调用)
通过地址做实验:
在 Class 上做一个实验:
var a = A(id: 1)
var a_copy = a
withUnsafePointer(to: &a) { (address) in
print("address of a (class) = \(address)")
}
withUnsafePointer(to: &a_copy) { (address) in
print("address of a_copy (class) = \(address)")
}
withUnsafePointer(to: &a.id) { (address) in
print("address of a.id (struct) = \(address)")
}
withUnsafePointer(to: &a_copy.id) { (address) in
print("address of a_copy.id (struct) = \(address)")
}
输出
address of a (class) = 0x0000000114747f80
address of a_copy (class) = 0x0000000114747f88
address of a.id (struct) = 0x000060000285a390
address of a_copy.id (struct) = 0x000060000285a390
观察 1:
class 的两个实例指的是其 属性 的相同位置。
让我们在 struct 上做实验:
print("\n\n\n")
withUnsafePointer(to: &b1) { (address) in
print("address of b1 (struct) = \(address)")
}
withUnsafePointer(to: &b1.grade) { (address) in
print("address of b1.grade (struct) = \(address)")
}
withUnsafePointer(to: &b1.a) { (address) in
print("address of b1.a (class) = \(address)")
}
withUnsafePointer(to: &b1.a.id) { (address) in
print("address of b1.a.id (class) = \(address)")
}
输出:
address of b1 (struct) = 0x0000000109382770
address of b1.grade (struct) = 0x0000000109382770
address of b1.a (class) = 0x0000000109382778
address of b1.a.id (class) = 0x0000600001e5cfd0
print("\n\n\n")
withUnsafePointer(to: ©_b1) { (address) in
print("address of copy_b1 (struct) = \(address)")
}
withUnsafePointer(to: ©_b1.grade) { (address) in
print("address of copy_b1.grade (struct) = \(address)")
}
withUnsafePointer(to: ©_b1.a) { (address) in
print("address of copy_b1.a (class) = \(address)")
}
withUnsafePointer(to: ©_b1.a.id) { (address) in
print("address of copy_b1.a.id (class) = \(address)")
}
输出:
address of copy_b1 (struct) = 0x0000000109382780
address of copy_b1.grade (struct) = 0x0000000109382780
address of copy_b1.a (class) = 0x0000000109382788
address of copy_b1.a.id (class) = 0x0000600001e5cfd0
结论:&b1.a.id 和 ©_b1.a.id 都引用相同的地址。
看来,我们不得不考虑修改对象(因为优化器会使用写时复制技术)
值类型(用户)包含引用类型(地址)
观察:
- On assignment of value type, any value type (ex: User) that contains a reference type (ex: Address), that reference type (ex: Address) is always passed as a reference.
引用类型(用户)包含值类型(地址)
观察:
- On assignment of reference type, any reference type (ex: User) contains value types (ex: Address), that value types (ex: Address) point to the same parent reference object (ex: User) (parent may contain many references - ex: both u1, u2 refers to same memory address).
如果我在 swift 中有一个带有 class 属性的结构并且我复制了结构对象,class 属性是通过引用复制还是传递?
参考通过。你可以测试一下。声明:
class A{}
struct B { let a = A()}
然后:
let b = B()
print("A = \(unsafeAddressOf(b.a))")//0x0000600000019450
let b_copy = b
print("A = \(unsafeAddressOf(b_copy.a))")//0x0000600000019450
一个结构的所有属性被复制(就像你分配(=
)旧结构的每个属性到相应的属性 的新结构)复制结构时,无论类型如何。
当您说 "class attribute" 时,我假设您指的是引用类型的变量。 (与 class 同名的类型表示指向该 class 对象的引用的引用类型。)复制引用类型(引用)的值会产生另一个指向同一个对象。请注意 "objects" 不是 Swift 中的值——没有 "object types" —— 相反,对象总是通过指向它们的引用来操作。
我在swift5测试了上面的实验: 让我们看看结果:
class A {
var id: Int
init(id: Int) {
self.id = id
}
}
struct B {
var grade: Int
var a: A
}
根据结果进行实验:
var a = A(id: 1)
var a_copy = a
var b1 = B(grade: 2, a: a)
var copy_b1 = b1
print(b1.a.id)
b1.a.id = 5
print(copy_b1.a.id)
print(b1.grade)
b1.grade = 3
print(copy_b1.grade)
输出:
1
5 // call by reference, same result
2
2 // call by value, no change in result
结论:
当我们创建它的另一个对象时,struct 会复制。它复制其结构 属性 (按值调用)但引用 class 属性 的相同实例(按引用调用)
通过地址做实验:
在 Class 上做一个实验:
var a = A(id: 1)
var a_copy = a
withUnsafePointer(to: &a) { (address) in
print("address of a (class) = \(address)")
}
withUnsafePointer(to: &a_copy) { (address) in
print("address of a_copy (class) = \(address)")
}
withUnsafePointer(to: &a.id) { (address) in
print("address of a.id (struct) = \(address)")
}
withUnsafePointer(to: &a_copy.id) { (address) in
print("address of a_copy.id (struct) = \(address)")
}
输出
address of a (class) = 0x0000000114747f80
address of a_copy (class) = 0x0000000114747f88
address of a.id (struct) = 0x000060000285a390
address of a_copy.id (struct) = 0x000060000285a390
观察 1:
class 的两个实例指的是其 属性 的相同位置。
让我们在 struct 上做实验:
print("\n\n\n")
withUnsafePointer(to: &b1) { (address) in
print("address of b1 (struct) = \(address)")
}
withUnsafePointer(to: &b1.grade) { (address) in
print("address of b1.grade (struct) = \(address)")
}
withUnsafePointer(to: &b1.a) { (address) in
print("address of b1.a (class) = \(address)")
}
withUnsafePointer(to: &b1.a.id) { (address) in
print("address of b1.a.id (class) = \(address)")
}
输出:
address of b1 (struct) = 0x0000000109382770
address of b1.grade (struct) = 0x0000000109382770
address of b1.a (class) = 0x0000000109382778
address of b1.a.id (class) = 0x0000600001e5cfd0
print("\n\n\n")
withUnsafePointer(to: ©_b1) { (address) in
print("address of copy_b1 (struct) = \(address)")
}
withUnsafePointer(to: ©_b1.grade) { (address) in
print("address of copy_b1.grade (struct) = \(address)")
}
withUnsafePointer(to: ©_b1.a) { (address) in
print("address of copy_b1.a (class) = \(address)")
}
withUnsafePointer(to: ©_b1.a.id) { (address) in
print("address of copy_b1.a.id (class) = \(address)")
}
输出:
address of copy_b1 (struct) = 0x0000000109382780
address of copy_b1.grade (struct) = 0x0000000109382780
address of copy_b1.a (class) = 0x0000000109382788
address of copy_b1.a.id (class) = 0x0000600001e5cfd0
结论:&b1.a.id 和 ©_b1.a.id 都引用相同的地址。
看来,我们不得不考虑修改对象(因为优化器会使用写时复制技术)
值类型(用户)包含引用类型(地址)
观察:
- On assignment of value type, any value type (ex: User) that contains a reference type (ex: Address), that reference type (ex: Address) is always passed as a reference.
引用类型(用户)包含值类型(地址)
观察:
- On assignment of reference type, any reference type (ex: User) contains value types (ex: Address), that value types (ex: Address) point to the same parent reference object (ex: User) (parent may contain many references - ex: both u1, u2 refers to same memory address).