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
    }
    // ...
}
马丁·R

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

var a = [1, 2, 3, 4]
var b = a

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

所以之后

b[0] = 17

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

a = b

a释放的旧元素存储,并且两个值再次都是指向相同存储的指针。

因此,在您的示例中:

    var y = propertyWithLongDescriptiveName
    // ... mutate y ...
    propertyWithLongDescriptiveName = y

元素存储的副本仅复制一次(假设您没有复制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]

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章