我想通过引用将我的Swift Array
account.chats
传递给chatsViewController.chats
(这样当我向account.chats
添加聊天时,chatsViewController.chats
仍然指向account.chats
)。即,当account.chats
的长度发生变化时,我不希望Swift将这两个数组分开。
答案 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中的Array
和Dictionary
作为结构实现。
答案 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)
使用NSMutableArray
或NSArray
这两个类
通过这种方式,您无需使用任何包装程序,就可以在桥接中使用构建版本
open class NSArray : NSObject, NSCopying, NSMutableCopying, NSSecureCoding, NSFastEnumeration