在赋值期间是否通过副本传递了结构中的swift类?

Nis*_*sba 12 struct class pass-by-reference pass-by-value swift

如果我在swift中有一个struct属性并且我复制了struct对象,那么class属性是通过引用复制还是传递的?

And*_*kha 22

通过引用传递.你可以测试一下.宣布:

class A{}
struct B { let a = A()}
Run Code Online (Sandbox Code Playgroud)

然后:

let b = B()
print("A = \(unsafeAddressOf(b.a))")//0x0000600000019450
let b_copy = b
print("A = \(unsafeAddressOf(b_copy.a))")//0x0000600000019450
Run Code Online (Sandbox Code Playgroud)


new*_*cct 7

在复制=结构时,无论类型如何,都会复制结构的所有属性(就像将旧结构的每个属性赋值给新结构的相应属性一样).

当你说"class attribute"时,我假设你的意思是引用类型的变量.(与类同名的类型表示指向该类对象的引用的引用类型.)复制引用类型(引用)的值会生成另一个指向同一对象的引用.请注意,"对象"不是Swift中的值 - 没有"对象类型" - 相反,对象始终通过指向它们的引用进行操作.


Ash*_*aha 5

我在swift 5中测试了上述实验:让我们看看结果:

class A {
    var id: Int
    init(id: Int) {
        self.id = id
    }
}

struct B {
    var grade: Int
    var a: A
}
Run Code Online (Sandbox Code Playgroud)

根据结果​​进行实验:

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)
Run Code Online (Sandbox Code Playgroud)

输出:

1
5 // call by reference, same result
2
2 // call by value, no change in result
Run Code Online (Sandbox Code Playgroud)

结论:

当我们创建它的另一个对象时,struct 会进行复制。它复制其结构属性(按值调用),但引用类属性的同一实例(按引用调用)

通过地址做实验:

在课堂上做一个实验:

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)")
}
Run Code Online (Sandbox Code Playgroud)

输出

address of a (class) = 0x0000000114747f80
address of a_copy (class) = 0x0000000114747f88
address of a.id (struct) = 0x000060000285a390
address of a_copy.id (struct) = 0x000060000285a390
Run Code Online (Sandbox Code Playgroud)

观察1:

该类的两个实例都引用其属性的同一位置。

让我们对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)")
}
Run Code Online (Sandbox Code Playgroud)

输出

address of b1 (struct) = 0x0000000109382770
address of b1.grade (struct) = 0x0000000109382770
address of b1.a (class) = 0x0000000109382778
address of b1.a.id (class) = 0x0000600001e5cfd0
Run Code Online (Sandbox Code Playgroud)
print("\n\n\n")
withUnsafePointer(to: &copy_b1) { (address) in
    print("address of copy_b1 (struct) = \(address)")
}
withUnsafePointer(to: &copy_b1.grade) { (address) in
    print("address of copy_b1.grade (struct) = \(address)")
}
withUnsafePointer(to: &copy_b1.a) { (address) in
    print("address of copy_b1.a (class) = \(address)")
}
withUnsafePointer(to: &copy_b1.a.id) { (address) in
    print("address of copy_b1.a.id (class) = \(address)")
}
Run Code Online (Sandbox Code Playgroud)

输出

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
Run Code Online (Sandbox Code Playgroud)

结论: &b1.a.id 和 ©_b1.a.id 都引用相同的地址。