基本上我想要的是类属性的临时别名,以提高可读性。
我遇到以下代码描述的情况,我看不到一个简单的解决方案。我想避免的是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
}
// ...
}
答案 0 :(得分:4)
struct Array
是Swift中的值类型,这意味着它们始终是
分配给另一个变量时复制。但是,每个struct Array
包含指向实际的指针(在公共接口中不可见)
元素存储。因此
var a = [1, 2, 3, 4]
var b = a
a
和b
都是(形式上独立的)值,但指向同一元素存储的指针。
只有当其中一个发生变异时,才会生成元素存储的副本。
这被称为"复制写入"例如在
所以
之后b[0] = 17
a
和b
是带有指向不同(独立)元素存储的指针的值。
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
到元素存储。
UnsafeMutableBufferPointer
是RandomAccessCollection
和
因此提供了类似阵列的接口。
答案 1 :(得分:2)
不,Swift编译器并不那么聪明。您只需要进行一项小测试即可了解它的作用:
class MyClass {
var propertyWithLongDescriptiveName: [Float] = [1,2]
func foo() {
var y = propertyWithLongDescriptiveName
y[0] = 3 // copied an mutated
print(y) // [3,2]
print(propertyWithLongDescriptiveName) // [1,2]
}
}
let mc = MyClass()
mc.foo()
你有2个选择:
propertyWithLongDescriptiveName
更改为NSMutableArray
,这是一种参考类型