这不是因为 Cocoa 类型是豁免的,而是因为NSMutableDictionary
是 a class
(而不是 a struct
),并且 theinout
并不代表您可能在想什么。
不幸的是,您链接到的文档(以及有关它链接到的参数的更深入的文档inout
)并没有清楚地说明“价值”的真正含义:
一个in-out参数有一个值,传入函数,被函数修改,传回函数外替换原来的值
以下语句暗示了一点,但可能更清楚:
您只能将变量作为输入输出参数的参数传递。您不能将常量或文字值作为参数传递,因为无法修改常量和文字。
文档描述的“值”是作为inout
. 对于值类型 ( struct
s),这是有意义的,因为每个持有这些类型值的变量都有效地持有该值的副本。
var a = MyGreatStruct(...)
var b = a
// a and b are not directly linked in any way
将 a传递struct
给函数通常会将值复制到新的局部变量中(新变量 = 副本),而您可以想象inout
让您直接访问原始变量(没有新变量)。
没有描述的是,对于行为不同的类,效果是相同的。
let a = MyGreatClass(...)
let b = a
// modifying `a` will modify `b` too since both point to the same instance
将 a传递class
给函数也会将该变量复制到一个新的局部变量中,但该副本没有意义——两个变量都持有相同的东西:对内存中对象本身的引用。从这个意义上说,复制并没有做任何特别的事情,您可以从函数内部修改对象,就像从外部修改对象一样。inout
for classes 的行为方式与 for struct
s 相同:它通过引用传递原始变量。这与您想要对对象执行的大多数操作无关(尽管它确实允许您使变量指向函数内的不同对象):
var a = MyGreatClass("Foo")
// func foo(_ value: MyGreatClass) {
// value = MyGreatClass("Bar") // <- not allowed since `value` isn't mutable
// }
func foo(_ value: inout MyGreatClass) {
value = MyGreatClass("Bar")
}
print(ObjectIdentifier(a)) // <some pointer>
foo(&a)
print(ObjectIdentifier(a)) // <some other pointer>