我真的是Swift的新手,我刚刚读到类是通过引用传递的,并且复制了数组/字符串等。
通过引用进行传递是否与在Objective-C或Java中通过“ a”引用进行传递的方式相同,还是通过引用进行正确传递?
我真的是Swift的新手,我刚刚读到类是通过引用传递的,并且复制了数组/字符串等。
通过引用进行传递是否与在Objective-C或Java中通过“ a”引用进行传递的方式相同,还是通过引用进行正确传递?
Answers:
规则是:
类实例是引用类型(即,您对类实例的引用实际上是一个指针)
函数是参考类型
其他一切都是价值类型 ; “其他所有内容”仅表示结构实例和枚举实例,因为这就是Swift中的全部内容。例如,数组和字符串是结构实例。正如newacct指出的那样,您可以通过使用inout
并获取地址来传递对其中之一的引用(作为函数参数)。但是类型本身就是一个值类型。
引用类型对象在实践中很特殊,因为:
仅仅分配或传递给函数可以产生对同一对象的多个引用
即使对对象的引用是一个常量(let
显式或隐式),对象本身也是可变的。
从对该对象的所有引用可以看出,对该对象的突变会影响该对象。
这些可能是危险,因此请注意。另一方面,传递引用类型显然是有效的,因为仅复制和传递了一个指针,这很简单。
显然,传递值类型是“安全的”,let
这意味着它所说的是:您不能通过let
引用对结构实例或枚举实例进行突变。另一方面,通过单独复制值来实现安全性,不是吗?这是否会使传递值类型变得昂贵?
好吧,是的,不是。它并不像您想象的那样糟糕。正如Nate Cook所说,传递值类型不一定意味着要进行复制,因为let
(显式或隐式)可以保证不变性,因此无需复制任何内容。甚至突入var
参考并不意味着事情会被复制,只有他们可以是如果需要的话(因为有一个突变)。该文档特别建议您不要扭曲您的内裤。
inout
类型,则为按值传递。某项是否通过引用与类型正交。
当参数不是时,它总是 按值传递inout
。
如果参数为,则始终 通过引用传递inout
。但是,&
由于在传递给参数时需要在参数上显式使用运算符inout
,因此此操作有些复杂,因此它可能不适合直接传递变量的传统“按引用传递”定义。
inout
)
inout
实际上不是通过引用传递的,而是通过复制复制的。它仅保证在函数调用后将修改后的值分配给原始参数。进出参数
默认情况下,Swift中的所有内容都通过“副本”传递,因此,当您传递值类型时,您将获得该值的副本,而当您传递引用类型时,您将获得该引用的副本,其中包括所有隐含的内容。(也就是说,引用的副本仍指向与原始引用相同的实例。)
我在上面的“副本”周围使用了吓人的引号,因为Swift做了很多优化。只要有可能,就不会复制,直到出现突变或突变的可能性为止。由于默认情况下参数是不可变的,因此这意味着大多数情况下实际上不会发生任何复制。
这是一个供参考传递的小代码示例。除非您有充分的理由,否则请避免这样做。
func ComputeSomeValues(_ value1: inout String, _ value2: inout Int){
value1 = "my great computation 1";
value2 = 123456;
}
这样称呼它
var val1: String = "";
var val2: Int = -1;
ComputeSomeValues(&val1, &val2);
inout
是一个复制,复制输出运算符。它将首先复制对象,然后在函数返回后覆盖原始对象。尽管看起来似乎相同,但存在细微的差异。
默认情况下,类通过引用传递,其他类则通过值传递。您可以使用inout
关键字通过引用传递。
inout
是一个复制,复制输出运算符。它将首先复制对象,然后在函数返回后覆盖原始对象。尽管看起来似乎相同,但存在细微的差异。