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