是Swift通过值或通过引用传递

我真的是新来的Swift,我刚刚读到的类通过引用传递和数组/string等被复制。

通过引用的传递方式与Objective-C或Java中的传递方式相同,其中您实际上传递了“a”引用,还是通过引用进行传递?

Swift中的事物types

规则是:

  • 类实例是引用types (即对类实例的引用实际上是一个指针

  • 函数是引用types

  • 其他一切都是价值型的 ; “其他所有”仅仅意味着结构和枚举实例的实例,因为这就是Swift中的全部。 例如,数组和string是结构实例。 正如newacct指出的那样,你可以通过使用inout和获取地址传递一个引用(作为函数参数)。 但是这种types本身就是一种价值types。

什么样的参考types为您

引用types对象在实践中是特殊的,因为:

  • 仅仅赋值或传递给函数可以产生对同一个对象的多个引用

  • 对象本身是可变的,即使对它的引用是一个常量(不pipe是明确的还是暗示的)。

  • 对象的变化会影响该对象,如所有引用所见。

那些可能是危险的,所以留意一下。 另一方面,传递引用types显然是有效的,因为只有一个指针被复制和传递,这是微不足道的。

什么样的价值types对于你

显然,传递一个值types是“更安全”的, let我们说一下:你不能通过let引用来改变结构实例或枚举实例。 另一方面,通过制作价值的单独副本来实现安全性,不是吗? 这不是通过一个价值types可能是昂贵的吗?

那么,是的,不。 这不像你想象的那样糟糕。 正如Nate Cook所说,传递一个值types并不一定意味着复制,因为let (明示或暗示)保证不变性,所以不需要复制任何东西。 甚至传入一个var引用并不意味着事物被复制,只有在必要的时候才会被复制(因为有一个变异)。 该文件特别build议你不要让你的内裤扭曲。

当参数不是inout时,它总是 传递值

如果参数是inout总是 通过引用 。 然而,这样做有点复杂,因为在传递给inout参数时需要在参数上显式使用&运算符,所以它可能不适合直接传递variables的传递引用的传统定义。

Swift中的所有东西默认都是通过“复制”来传递的,所以当你传递一个值types的时候,你会得到一个值的副本,当你传递一个引用types时,你会得到一个引用的副本。 (也就是说,引用的副本仍然指向与原始引用相同的实例。)

我在上面的“副本”中使用了惊吓语句,因为Swift做了很多优化; 只要有可能,它不会复制,直到有突变或突变的可能性。 由于默认参数是不可变的,这意味着大部分时间没有实际发生拷贝。

Apple Swift开发者博客有一篇名为“ 值和参考types”的文章 ,对这个主题进行了清晰而详细的讨论。

去引用:

Swift中的types可以分为两类:第一类是“值types”,其中每个实例保存其数据的唯一副本,通常定义为结构,枚举或元组。 第二种是“引用types”,其中实例共享数据的单个副本,而types通常被定义为一个类。

Swift博客文章继续用示例解释不同之处,并build议何时使用它们。

类通过引用传递,其他类通过默认值传递。 您可以通过使用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);