Swift通过价值或通过参考传递

时间:2014-12-08 18:06:56

标签: swift pass-by-reference pass-by-value pass-by-pointer

我对Swift很新,我只是读取了类通过引用传递,数组/字符串等被复制。

传递引用是否与Objective-C或Java中的传递方式相同,其中实际传递的是#34; a"参考或通过引用正确传递?

9 个答案:

答案 0 :(得分:149)

Swift中的事物类型

规则是:

  • 类实例是引用类型(即您的对类实例的引用实际上是指针

    < / 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 获取passreturnreference type一个值{1}}

[Value vs Reference type]

如果与Value Type进行比较,则可以找到匹配项:

  • Java参考类型(所有对象)
  • Java基本类型(int,bool ...)-Swift使用Java扩展它