通过引用传递数组?

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

94283 次浏览

差不多

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

???

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

定义一个实现 Array接口但将所有函数委托给存储属性的 BoxedArray<T>

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


// ...


subscript (index: Int) -> T {
get { return array[index] }
set(newValue) { array[index] = newValue }
}
}

在任何使用 Array的地方使用 BoxedArrayBoxedArray的赋值将通过引用进行,它是一个类,因此通过 Array接口对存储属性的更改对所有引用都是可见的。

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

let (这是默认操作符,所以我们可以省略 ) ,使参数常量(这意味着我们甚至不能修改本地副本) ; < br >
使其可变(我们可以在本地修改它,但它不会影响传递给函数的外部变量) ;
inout 使其成为一个 in-out 参数。In-out 实际上是指通过引用而不是通过值传递变量。它不仅需要通过引用接受值,还需要通过引用传递值,因此使用 &-foo(&myVar)传递值,而不仅仅是 foo(myVar)

所以这样做:

var arr = [1, 2, 3]


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


addItem(&arr)
print(arr) // it will print [1, 2, 3, 4]

确切地说,它不仅仅是一个引用,而是外部变量的一个真实别名,所以你可以对任何变量类型使用这样的技巧,例如,整数(你可以给它赋新值) ,尽管这可能不是一个好的做法,像这样修改原始数据类型可能会让人感到困惑。

另一种选择是让数组的使用者根据需要请求所有者。例如:

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 类中随心所欲地修改数组。注意,如果您还想修改视图控制器类中的数组,这对您没有帮助。

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

var arr = [1, 2, 3]


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


addItem(&arr)
print(arr)

使用 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]

使用 NSMutableArrayNSArray,它们都是类

这样,您就不需要实现任何包装器,并且可以在桥接中使用构建

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

根据 GoZoner 的 BoxedArray答案,我创建了下面这个对我有用的类。我喜欢将数组作为引用传递的自由(就像我使用的其他语言一样)。

class MArray<T> : MutableCollection {
    

var array : Array<T> = Array()
var count: Int { return array.count }   // getter (without, index func below will be called repeatedly to determine)
    

func add(_ value: T) {
array.append(value)
}


// MutableCollection requires:
subscript (index: Int) -> T {
get { return array[index] }
set(value) { array[index] = value }
}
var startIndex: Int {
return 0
}
var endIndex: Int {
return array.count
}
func index(after i: Int) -> Int {
return i+1
}
}