在这种情况下,Swift是否会复制突变?

Fre*_*uid 6 memory swift

基本上我想要的是类属性的临时别名,以提高可读性.

我遇到以下代码描述的情况,我看不到一个简单的解决方案.我想避免的是y复制突变然后复制回来.重命名y会大大降低实际算法的可读性.

Swift编译器是否足够智能,不能实际分配新内存,我怎么能知道呢?

如果没有,如何防止复制?

class myClass {
    var propertyWithLongDescriptiveName: [Float]

    func foo() {
        var y = propertyWithLongDescriptiveName
        // mutate y with formulas where y corresponds to a `y` from some paper
        // ...
        propertyWithLongDescriptiveName = y
    }
    // ...
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*n R 4

struct Array是 Swift 中的值类型,这意味着它们在分配给另一个变量时总是会被复制。但是,每个都struct Array 包含指向实际元素存储的指针(在公共接口中不可见)。因此之后

var a = [1, 2, 3, 4]
var b = a
Run Code Online (Sandbox Code Playgroud)

a都是b(形式上独立的)值,但具有指向相同元素存储的指针。仅当其中之一发生变异时,才会制作元素存储的副本。这称为“写入时复制”,例如在

所以之后

b[0] = 17
Run Code Online (Sandbox Code Playgroud)

ab是带有指向不同(独立)元素存储的指针的值。的进一步变异b不会再次复制元素存储(除非b复制到另一个变量)。最后,如果您将值赋回

a = b
Run Code Online (Sandbox Code Playgroud)

的旧元素存储a被释放,并且两个值再次成为指向同一存储的指针。

因此在你的例子中:

    var y = propertyWithLongDescriptiveName
    // ... mutate y ...
    propertyWithLongDescriptiveName = y
Run Code Online (Sandbox Code Playgroud)

元素存储的副本只制作一次(假设您不复制y到其他变量)。

如果数组大小不变,则可能的方法是

var propertyWithLongDescriptiveName = [1.0, 2.0, 3.0, 4.0]

propertyWithLongDescriptiveName.withUnsafeMutableBufferPointer { y in
    // ... mutate y ...
    y[0] = 13
}

print(propertyWithLongDescriptiveName) // [13.0, 2.0, 3.0, 4.0]
Run Code Online (Sandbox Code Playgroud)

withUnsafeMutableBufferPointer()使用 an UnsafeMutableBufferPointer来调用元素存储的闭包。AUnsafeMutableBufferPointer是 a RandomAccessCollection,因此提供了类似数组的接口。