是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);