Swift:通过引用传递数组?

时间:2014-06-16 19:38:41

标签: arrays swift pass-by-reference

我想通过引用将我的Swift Array account.chats传递给chatsViewController.chats(这样当我向account.chats添加聊天时,chatsViewController.chats仍然指向account.chats)。即,当account.chats的长度发生变化时,我不希望Swift将这两个数组分开。

8 个答案:

答案 0 :(得分:128)

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

(它的默认操作符,因此我们可以省略)使参数保持不变(这意味着我们无法修改本地副本);

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

inout 使其成为输入输出参数。 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]

确切地说,它不仅仅是一个引用,而是外部变量的真正别名,因此您可以使用任何变量类型执行此类操作,例如使用整数(您可以为其指定新值)虽然这可能不是一个好习惯,但修改这样的原始数据类型可能会让人感到困惑。

答案 1 :(得分:60)

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

答案 2 :(得分:21)

定义一个实现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 }
  }
}

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

答案 3 :(得分:15)

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

var arr = [1, 2, 3]

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

addItem(&arr)
print(arr)

答案 4 :(得分:3)

这样的东西
var a : Int[] = []
func test(inout b : Int[]) {
    b += [1,2,3,4,5]
}
test(&a)
println(a)

???

答案 5 :(得分:2)

另一个选择是让阵列的消费者根据需要向所有者询问。例如,类似于:

class Account {
    var chats : [String]!
    var chatsViewController : ChatsViewController!

    func InitViewController() {
        chatsViewController.getChats = { return self.chats }
    }

}

class ChatsViewController {
    var getChats: (() -> ([String]))!

    func doSomethingWithChats() {
        let chats = getChats()
        // use it as needed
    }
}

然后,您可以在Account类中根据需要修改数组。请注意,如果您还想从视图控制器类修改数组,这对您没有帮助。

答案 6 :(得分:0)

使用inout是一种解决方案,但由于数组是值类型,因此对我来说感觉不太开心。在风格上,我个人更喜欢返回变异副本:

func doSomething(to arr: [Int]) -> [Int] {
    var arr = arr
    arr.append(3) // or likely some more complex operation
    return arr
}

var ids = [1, 2]
ids = doSomething(to: ids)
print(ids) // [1,2,3]

答案 7 :(得分:0)

使用NSMutableArrayNSArray这两个类

通过这种方式,您无需使用任何包装程序,就可以在桥接中使用构建版本

open class NSArray : NSObject, NSCopying, NSMutableCopying, NSSecureCoding, NSFastEnumeration