我对 Swift 很陌生,我刚刚读到类是通过引用传递的,而数组/字符串等是被复制的。
通过引用传递是否与在 Objective-C 或 Java 中实际传递“a”引用的方式相同,还是按引用传递是正确的?
我对 Swift 很陌生,我刚刚读到类是通过引用传递的,而数组/字符串等是被复制的。
通过引用传递是否与在 Objective-C 或 Java 中实际传递“a”引用的方式相同,还是按引用传递是正确的?
规则是:
类实例是引用类型(即您对类实例的引用实际上是一个指针)
函数是引用类型
其他一切都是值类型;“其他一切”只是指结构实例和枚举实例,因为这就是 Swift 中的全部内容。例如,数组和字符串是结构实例。正如 newacct 所指出的,您可以通过使用和获取地址来传递对其中一个事物的引用(作为函数参数) 。inout
但是类型本身就是一个值类型。
引用类型对象在实践中是特殊的,因为:
仅仅赋值或传递给函数可以产生对同一个对象的多个引用
对象本身是可变的,即使对它的引用是一个常量(let
无论是显式的还是隐含的)。
对对象的突变会影响该对象,正如所有对它的引用所看到的那样。
这些可能是危险的,所以要小心。另一方面,传递引用类型显然是有效的,因为只复制和传递了一个指针,这是微不足道的。
显然,传递一个值类型是“更安全的”,let
这意味着它所说的:你不能通过let
引用来改变结构实例或枚举实例。另一方面,安全性是通过制作价值的单独副本来实现的,不是吗?这不会使传递值类型可能很昂贵吗?
嗯,是的,也不是。它并不像你想象的那么糟糕。正如 Nate Cook 所说,传递值类型并不一定意味着复制,因为let
(显式或隐式)保证不变性,因此无需复制任何内容。甚至传递到var
引用并不意味着将复制事物,只是在必要时可以复制它们(因为存在突变)。文档特别建议您不要扭曲内裤。
默认情况下,Swift 中的所有内容都是通过“复制”传递的,所以当你传递一个值类型时,你会得到一个值的副本,而当你传递一个引用类型时,你会得到一个引用的副本,这意味着。(也就是说,引用的副本仍然指向与原始引用相同的实例。)
我在上面的“复制”周围使用了吓人的引号,因为 Swift 做了很多优化;只要有可能,它就不会复制,直到发生突变或可能发生突变。由于默认情况下参数是不可变的,这意味着大多数情况下实际上不会发生复制。
当参数不是时,它总是 按值传递inout
。
如果参数为,则始终是 按引用传递inout
。但是,这有点复杂,因为您需要&
在传递给参数时显式地在参数上使用运算符inout
,因此它可能不符合直接传递变量的传统引用传递定义。
这是一个通过引用传递的小代码示例。避免这样做,除非你有充分的理由这样做。
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);
Apple Swift 开发人员博客有一篇名为Value and Reference Types的文章,对这个主题进行了清晰而详细的讨论。
去引用:
Swift 中的类型属于以下两类之一:第一,“值类型”,其中每个实例都保留其数据的唯一副本,通常定义为结构、枚举或元组。第二种,“引用类型”,实例共享数据的一个副本,类型通常定义为一个类。
Swift 博客文章继续通过示例解释差异,并建议您何时使用其中一个。
当您将 inout 与 += 等中缀运算符一起使用时,可以忽略 &address 符号。我猜编译器假设通过引用传递?
extension Dictionary {
static func += (left: inout Dictionary, right: Dictionary) {
for (key, value) in right {
left[key] = value
}
}
}
origDictionary += newDictionaryToAdd
很好的是,这本字典“添加”也只对原始参考进行了一次写入,非常适合锁定!
类和结构
结构和类之间最重要的区别之一是结构在代码中传递时总是被复制,但类是通过引用传递的。
闭包
如果您将闭包分配给类实例的属性,并且闭包通过引用实例或其成员来捕获该实例,您将在闭包和实例之间创建一个强引用循环。Swift 使用捕获列表来打破这些强引用循环
ARC(自动引用计数)
引用计数仅适用于类的实例。结构和枚举是值类型,而不是引用类型,并且不是通过引用存储和传递的。
默认情况下,类通过引用传递,其他类通过值传递。inout
您可以使用关键字通过引用传递。
Swift assign
,pass
以及return
通过引用reference type
和复制的值Value Type
如果与您比较,Java
您可以找到匹配项:
struct