这是一个关于 Swift 可选堆栈对象(例如 struct)和“if let”的 Swift 编译器优化问题。
在 Swift 中,“if let”为您提供了一个语法糖来处理可选项。 住在堆栈上的结构呢?作为一名 C++ 程序员,我不会引入不必要的堆栈对象副本,尤其是,只是为了检查它是否存在于容器中。每次您使用“if let”时,是否递归地复制结构及其所有成员,或者 swift 编译器是否已优化到足以通过引用或使用其他技巧创建局部变量?
例如,我们将这个结构体打包成一个可选的:
struct MyData{
var a=1
var b=2
//lots more store....
func description()->String{
return "MyData: a="+String(a)+", b="+String(b)
}
}
var optionalData:MyData?=nil
optionalData=MyData()
由于结构在堆栈上,要解包,是否存在从容器 optionalData 到本地 var 数据的不必要副本,或者数据是常量这一事实,副本被优化掉了吗?
if let data=optionalData{//is data copy or reference?
println(data.description())
}
最佳答案
since the struct is on the stack, to unpack, is there an unnecessary copy from the container optionalData to local var data, or the fact that the data is a constant, the copy is optimized away?
编译器不太可能实际发出代码来制作副本。 let
本质上是给表达式另一个名字。
对于类,“let x = y”将允许您遍历 x 的副本(因为您只是复制一个引用),即
let x = y
x.foo = bar
y.foo // => bar
但对于结构,情况并非如此。不允许写入 let
结构或对其调用任何 mutable
方法。这允许 Swift 编译器将 let x = y
(其中 y 是一个结构)视为空操作。
但是,这段代码可能确实复制了 y
:
y.foo = bar
let x = y
y.foo = baz
x.foo // => bar
它必须如此,因为您写信给了您正在复制的内容。这称为“写时复制”,这是一种通过使用 let
语义实现的优化。
回答你的最后一个问题:
if let data=optionalData{//is data copy or reference?
println(data.description())
}
在这种情况下,数据无疑是一个引用。实际上它可能根本不存在;编译器将发出与您编写的代码相同的代码:
if (optionalData != nil)
{
println(optionalData!.description())
}
关于optimization - 使用 "if let"解包堆栈对象(例如结构),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24075599/