使用Swift(Pre Swift 3)通过引用调用与按值调用

如果您是刚开始编程的人,没有太多的经验或对指针,地址和所有内存内容的了解,那么您可能会困惑于按引用调用(发生在类中)和按值调用(发生在结构中)。 如果您已经知道函数调用是什么,那么希望这对您有所帮助,使您在头脑中的区别更加清晰。

下面是显示内存和值差异的基本图。 物理内存地址是保存数据的位置。 该值就是该地址中保存的值。 了解这种差异很重要。

调用带有参数(或多个参数)的函数时,它可以采用值(整数,双精度型等)或引用(对象的实例)。 我们将从引用调用函数开始:

通过引用调用函数

当您有一个对象的实例,并将其分配给一个变量时,该变量实际上将保存该实例的物理地址。 因此,当您将其作为参数左右传递给不同的函数时,仅传递其地址比将整个对象移动更为有效,因为仅保存地址信息的变量所占用的存储空间比对象本身少(4个字节) (32位系统)和8位元组(64位系统)。

当变量的物理地址在调用函数时作为参数传递给函数时,可以说该函数是通过引用来调用的。 发生了什么事? 由于仅传递变量的地址,因此对该地址中的变量进行任何更改,该更改与调用函数时使用的变量相同! 因此,对变量进行的任何更改都会更改变量本身! 下面是一段代码和变量以及相关变量的地址的打印输出:

如您所见,当我们通过引用调用函数callMeByReference时,传递someNumber的地址,并在该函数内部更改该地址中的值时,它将更改someNumber的值,因为它是该地址中的变量! 在调用函数后打印出someNumber的值时,其值已更改! (即使函数不返回任何值)

通过值调用函数

但是,当您通过值调用函数时,会将参数复制(克隆)到内存的其他地址中。 即使给参数提供了与调用函数时使用的变量相同的名称,它也将是不同的变量(具有局部作用域,这意味着它仅在执行时才存在于函数体内)

为了证明我们的观点,请参见下面的代码和输出示例*:

所以,我们开始! 在将变量传递给函数callMeByReference及其地址0x0000000112097750之前,变量anotherNumber的值为3。 当函数具有参数anothermethod时,其值也为3,但其地址不同! 因为它与另一个Number不同,所以它只是一个克隆(代理人-布鲁斯威利斯的粉丝!!!)!

因此,即使我们更改参数anotherNumber的值,也不会更改函数外部的变量anotherNumber的值。 调用函数后,我们将输出anotherNumber变量的值和地址,但它们都没有改变,这证明了我们的观点!

我希望这可以帮助别人!

*请不要很快就弃用“ var”参数。它们必须是一个常量(“ let”)。