基本上我想要的是类属性的临时别名,以提高可读性.
我遇到以下代码描述的情况,我看不到一个简单的解决方案.我想避免的是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)
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)
a和b是带有指向不同(独立)元素存储的指针的值。的进一步变异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,因此提供了类似数组的接口。