Swift 通过引用传递常量参数

Swift 通过引用传递常量参数,swift,constants,pass-by-reference,Swift,Constants,Pass By Reference,如何通过引用传递常量参数 在Swift中,可以仅对变量执行此操作(并使用inout关键字) 我可以通过引用传递常数吗 我想这样做: let x = ["a":1, "b":2] myFunc(&x) 不能将let常量传递给inout参数 据 输入输出参数的传递方式如下: 调用函数时,将复制参数的值 在函数体中,修改副本 当函数返回时,副本的值被赋给原始参数 这会自动取消let常量的资格,因为它们无法重新分配 我可以通过引用传递常数吗 我不知道。但是,您不应该自己这样做 在您使用词典

如何通过引用传递常量参数

在Swift中,可以仅对变量执行此操作(并使用
inout
关键字)

我可以通过引用传递常数吗

我想这样做:

let x = ["a":1, "b":2]
myFunc(&x)

不能将
let
常量传递给
inout
参数

输入输出参数的传递方式如下:

  • 调用函数时,将复制参数的值
  • 在函数体中,修改副本
  • 当函数返回时,副本的值被赋给原始参数
这会自动取消
let
常量的资格,因为它们无法重新分配

我可以通过引用传递常数吗

我不知道。但是,您不应该自己这样做

在您使用
词典
提出的特定情况下,您处理的是间接存储其内容的集合。在最简单的层次上,您可以将其视为一个只有一个属性的结构,该属性只是对字典的键和值的实际存储的引用

按值传递该结构(字典)相当于只传递一个关于的引用。多个字典可以通过该引用查看相同的键值存储。但是,如果需要的话,存储的唯一副本将进行变异—这称为写时复制,并允许值语义,而无需每次复制字典结构时复制整个缓冲区的开销

因此,这里绝对不需要通过引用传递。只需按正常方式传递字典(即按值传递–即,不使用
&
,例如使用
inout
和指针参数)

在更一般的情况下,如果您希望在向函数传递值时避免复制大型结构,编译器已经介绍了这一点。它可以执行各种巧妙的优化,以减少复制;其中之一是通过引用将结构传递给函数。我将对此进行更详细的介绍

这真的不是你需要考虑的事情,除非:

  • 实际上,您需要调用方端变异(在这种情况下,您仍然需要
    var

  • 您已经明确指出了一个性能瓶颈(在这种情况下,您很可能受益于创建自己的写时拷贝结构)


谢谢。是的,我知道。“这么说斯威夫特做不到,是吗?”瑞克说得对。他们甚至删除了Swift 3中的
var
,这杀死了一个可能有用的调用方突变案例。@dasblinkenlight你的意思是
var
参数,对吗?但是,他们实际上不允许调用方突变,它只是被调用方的一个可变副本(事实上,它被删除的原因之一是与
inout
的调用方突变行为混淆)。我想这样做:为什么?你从来没有说过你为什么要这么做。因为
x
非常大。你是对的。字典是结构,因此通过值传递,这意味着创建了副本。在幕后,斯威夫特将做有效的事情,而不是创建字典的第二个副本。@作为引用或值类型与它是通过引用还是通过值传递是正交的。通常,Swift中的参数总是按值传递,除非使用
&
传递(例如可以使用
inout
UnsafeMutablePointer
参数传递)。如果有
[String:Int]
参数,则传递给它的字典将按值传递。但是,正如我前面所说,
Dictionary
将其键+值间接存储在一个引用计数的缓冲区中(对于本机,实际上是两个缓冲区)。仅按值传递
Dictionary
不会复制那些底层缓冲区(仅复制指向这些缓冲区的指针!)。调用者和被调用者对相同的缓冲区都有一个视图(但在发生突变时,他们将获取自己的副本,这称为写时复制)。由于这个原因,你真的不需要通过引用传递字典。