Swift:通过引用传递数组?

ma1*_*w28 118 arrays pass-by-reference swift

我想我的雨燕传递Array account.chatschatsViewController.chats引用(这样当我加入聊天account.chats,chatsViewController.chats仍然指向account.chats).即,我不希望Swift在account.chats更改长度时将两个数组分开.

小智 133

对于函数参数运算符,我们使用:

let(它的默认运算符,所以我们可以省略let)使参数变为常量(这意味着我们甚至不能修改本地副本);

var使其变量(我们可以在本地修改它,但它不会影响已传递给函数的外部变量); 并且

inout使它成为in-out参数.In-out实际上意味着通过引用而不是通过值传递变量.它不仅要求通过引用接受值,还要通过引用传递它,所以将它传递给& - foo(&myVar)而不仅仅是foo(myVar)

所以这样做:

var arr = [1, 2, 3]

func addItem(inout localArr: [Int]) {
    localArr.append(4)
}

addItem(&arr)    
println(arr) // it will print [1, 2, 3, 4]
Run Code Online (Sandbox Code Playgroud)

确切地说,它不仅仅是一个引用,而是外部变量的真正别名,因此您可以使用任何变量类型执行此类技巧,例如使用整数(您可以为其指定新值),尽管它可能不是良好的做法,修改像这样的原始数据类型可能会令人困惑.

  • 这并没有真正解释如何使用数组作为未被复制引用的实例变量. (10认同)
  • 在Swift 3中,`inout`位置已经改变,即`func addItem(localArr:inout [Int])` (10认同)
  • 我以为inout使用了一个getter和一个setter来将数组复制到一个临时的,然后在离开函数的路上重置它 - 即它复制 (2认同)
  • 实际上输入输出使用copy-in copy-out或按值调用结果.但是,作为优化,它可以通过引用使用."作为优化,当参数是存储在内存中物理地址的值时,在函数体内部和外部都使用相同的内存位置.优化的行为称为引用调用;它满足所有要求复制拷贝模型,同时消除了复制的开销." (2认同)
  • 同样,`var`不再对函数参数属性可用。 (2认同)

Kaa*_*glu 66

Swift中的结构是按值传递的,但您可以使用inout修饰符来修改数组(请参阅下面的答案).类通过引用传递.ArrayDictionary在Swift中实现为结构.

  • @Boon数组仍然在语义上被复制/按值传递,但只是优化使用[COW](http://en.wikipedia.org/wiki/Copy-on-write). (12认同)
  • 我不建议使用`NSArray`,因为`NSArray`和Swift数组有明显的语义差异(比如引用类型),这可能会导致更多错误. (4认同)
  • 数组不会被Swift中的值复制/传递 - 与常规结构相比,它在Swift中的行为非常不同.请参阅http://stackoverflow.com/questions/24450284/conflicting-definition-of-struct-and-array/24454610#24454610 (2认同)
  • 这真的要了我的命。我在敲我的头,为什么事情不正常。 (2认同)
  • 如果在结构中使用`inout`怎么办? (2认同)

GoZ*_*ner 22

定义自己BoxedArray<T>实现Array接口,但将所有函数委托给存储的属性.因此

class BoxedArray<T> : MutableCollection, Reflectable, ... {
  var array : Array<T>

  // ...

  subscript (index: Int) -> T { 
    get { return array[index] }
    set(newValue) { array[index] = newValue }
  }
}
Run Code Online (Sandbox Code Playgroud)

使用BoxedArray您使用的任何地方Array.BoxedArray通过引用分配a 将是一个类,因此通过Array接口对存储属性的更改将对所有引用可见.

  • 我只是觉得将Array定义为struct而不是class是语言设计错误. (9认同)

小智 18

对于Swift版本3-4(XCode 8-9),请使用

var arr = [1, 2, 3]

func addItem(_ localArr: inout [Int]) {
    localArr.append(4)
}

addItem(&arr)
print(arr)
Run Code Online (Sandbox Code Playgroud)