是通过值快速传递还是通过引用快速传递

我对 Swift 真的很陌生,我刚刚读到类是通过引用传递的,数组/字符串等是复制的。

引用传递是否与在 Objective-C 或 Java 中实际传递“ a”引用的方式相同,或者是否正确的引用传递方式?

100422 次浏览

Swift 中的所有内容在默认情况下都是通过“ copy”传递的,因此当您传递一个值类型时,您将获得该值的一个副本,当您传递一个引用类型时,您将获得该引用的一个副本,这就意味着。(也就是说,引用的副本仍然指向与原始引用相同的实例。)

我在上面的“复制”周围使用了引号,因为 Swift 进行了大量的优化; 只要有可能,它就不会复制,直到出现突变或可能出现突变。由于参数在默认情况下是不可变的,这意味着大多数情况下不会实际发生复制。

当参数不是 inout时,它是 一直都是 按值传递(pass-by-value)

如果参数为 inout,则为 一直都是 通过引用传递。但是,当传递给 inout参数时,需要在参数上显式使用 &操作符,这使得问题有些复杂,因此它可能不适合传递引用的传统定义,即直接传递变量。

Swift 中的事物类型

规则是:

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

  • 函数是引用类型

  • 其他所有内容都是 值类型; “其他所有内容”只是指结构的实例和枚举的实例,因为 Swift 中只有这些内容。例如,数组和字符串是结构实例。如 newacct 所指出的,通过使用 inout并获取地址,可以可以传递对其中之一的引用(作为函数参数)。但类型本身是一个值类型。

参考类型对你意味着什么

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

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

  • 对象本身是可变的,即使对它的引用是一个常量(let,显式的或隐含的)。

  • 对象的突变会影响该对象,所有对该对象的引用都会看到这一点。

那些可能是危险的,所以要小心。另一方面,传递引用类型显然是有效的,因为只复制和传递一个指针,这是微不足道的。

价值类型对你意味着什么

显然,传递一个值类型是“更安全的”,而 let的意思就是: 您不能通过 let引用来变异一个 struct 实例或枚举实例。另一方面,这种安全是通过单独复制价值来实现的,不是吗?这是否会使传递值类型的代价变得潜在地昂贵?

是也不是。没你想的那么糟。正如 Nate Cook 所说,传递值类型并不意味着复制,因为 let(显式或隐式)保证了不变性,所以不需要复制任何东西。甚至传入一个 var参考并不意味着事物 威尔被复制,只是他们 可以是如果必要的(因为有一个突变)。医生特别建议你不要紧张。

苹果 Swift 开发者博客有一篇名为 值和引用类型 的文章,提供了关于这个主题的清晰而详细的讨论。

引用如下:

Swift 中的类型分为两类: 第一类,“值类型”, 其中每个实例保持其数据的唯一副本,通常定义 作为结构、枚举或元组。第二个,“引用类型”,其中 实例共享数据的单个副本,并且类型通常是 定义为一个类。

Swift 的博客文章继续用例子来解释这些差异,并建议什么时候应该使用其中一个。

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

当您将 inout 与 + = 等中缀操作符一起使用时,可以忽略 & 地址符号。我猜编译器假设通过引用?

extension Dictionary {
static func += (left: inout Dictionary, right: Dictionary) {
for (key, value) in right {
left[key] = value
}
}
}

OrigDictionary + = newDictionaryToAdd

很好,这个字典“ add”也只写到原始引用,非常适合锁定!

类别及结构

结构和类之间最重要的区别之一是,当结构在代码中传递时,它们总是被复制,但类是通过引用传递的。

关闭

如果将闭包分配给类实例的属性,并且闭包通过引用实例或其成员来捕获该实例,则将在闭包和实例之间创建一个强引用循环。Swift 使用捕获列表来打破这些强引用周期

自动参考计数

引用计数仅适用于类的实例。结构和枚举是值类型,而不是引用类型,并且不通过引用存储和传递。

雨燕 assignpassreturn的值由 参考文献reference type和由 收到Value Type

[ Value vs Reference type ]

如果与 Java比较,你可以找到匹配的:

  • Java 引用类型(所有对象)
  • Java 原语类型(int,bool...)-Swift 使用 struct扩展它

Struct 是一个值类型,因此它总是作为值传递

    //STEP 1 CREATE PROPERTIES
struct Person{
var raw : String
var name: String
var age: Int
var profession: String
// STEP 2 CREATE FUNCTION
func personInformation(){
print("\(raw)")
print("name : \(name)")
print("age : \(age)")
print("profession : \(profession)")
}
}
//allow equal values
B = A then call the function
A.personInformation()
B.personInformation()
print(B.name)

当我们更改“ B”的值时,也会得到相同的结果,只是因为复制了 A 的值,所以在 B 中发生了更改,如 名字 = “ Zainab” 一个改变发生在 B 的名字。它是通过值

通过引用传递 类总是使用通过引用,其中只有占用内存的地址被复制,当我们改变类似于在结构改变 B 的值,A 和 B 都改变,因为引用被复制,。