使用“if let”解压缩堆栈对象(例如结构)

时间:2014-06-06 06:30:35

标签: optimization struct swift

这是关于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()

因为struct在堆栈上,要解压缩,是否有一个从容器optionalData到本地var数据的不必要的副本,或者数据是常量的事实,副本是否被优化掉了?

if let data=optionalData{//is data copy or reference?
    println(data.description())
}

1 个答案:

答案 0 :(得分:3)

  

因为struct在堆栈上,要解压缩,是否有一个从容器optionalData到本地var数据的不必要的副本,或者数据是常量的事实,副本是否被优化掉了?

编译器不太可能实际发出代码来制作副本。 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

它必须,因为你写了你正在复制的东西。这被称为" copy-on-write",它是通过使用let语义实现的优化。

回答你的最后一个问题:

if let data=optionalData{//is data copy or reference?
    println(data.description())
}
在这种情况下,

数据肯定是一个参考。实际上它可能根本不存在;编译器将发出与您编写的相同的代码:

if (optionalData != nil)
{    
    println(optionalData!.description())
}