我决定更新我在Swift beta 1期间制作的项目,现在Swift 1.0已经用完了。但是,由于更新的数组语义和inout
关键字,我似乎无法解决这个问题。考虑以下两个功能(您可以将它们粘贴到游乐场中):
func bubbleSort<T : Comparable>(inout arr : [T]) {
var numSwaps = 0
do {
numSwaps = 0
for i in 0..<(arr.count - 1) {
if arr[i] > arr[i + 1] {
(arr[i], arr[i + 1]) = (arr[i + 1], arr[i])
numSwaps++
}
}
} while numSwaps != 0
}
func testFunc(sortFunc: ([Int]) -> ()) {
sortFunc([5,4,3,2,1])
}
我似乎无法让两者协同工作。我尝试使用速记:
testFunc {bubbleSort(&$0)}
我也试过没有速记:
testFunc { (arr: [Int]) -> () in
bubbleSort(&arr)
}
在任何一种情况下,我都会收到错误:
这是一个错误,还是我搞砸了什么?提前谢谢!
答案 0 :(得分:3)
您遇到的是默认情况下方法参数是不可变的,而输入输出函数是变异的。你不能使用闭包速记,因为你需要使用var
关键字将闭包的参数声明为可变的,如下所示:
func testFunc(sortFunc: ([Int]) -> ()) {
sortFunc([5,4,3,2,1])
}
testFunc { (var arr: [Int]) -> () in
bubbleSort(&arr)
}
现在,您可以使用bubbleSort
作为输入输出参数调用arr
。
答案 1 :(得分:2)
您遇到的是beta 3的变化(如果我没记错的话),更改数组的en元素变为mutating
操作。在此之前,更改元素是非变异操作,因此您可以更改Array
常量上的元素;你无法改变它的长度。但是从beta 3开始,要更改数组中的元素,它必须是非常量的。
bubbleSort
通过引用(inout
)获取数组,因为它需要更改数组的元素并使其对调用者可见(在beta 3之前,它只是按值获取) 。您只能通过引用传递非常量变量。在您写的闭包中,arr
是一个常量(它是一个未声明为var
或inout
的数组参数),因此您无法通过引用传递它。
显而易见的答案是arr
必须是var
或inout
。您需要哪一个取决于这些功能的目的。你现在所拥有的是丢弃调用的结果,这是毫无意义的,所以你显然没有告诉我们这些功能应该做什么。
@ NakeCook的回答,只需让arr
成为var
,就可以通过引用传递它,但它并没有改变闭包采用其参数的事实by value(以及sortFunc
中的testFunc
是一个按值传递的函数。这意味着testFunc
给函数排序一个数组,但不关心或想要更改要反映回来。如果这是你想要的,那就是答案。
但是,如果testFunc
应该有一个数组,将它传递给sort函数进行排序,并希望在其范围内看到对数组的更改,那么它需要做其他事情:
func testFunc(sortFunc: (inout [Int]) -> ()) {
var x = [5,4,3,2,1]
sortFunc(&x)
}
testFunc { (inout arr: [Int]) -> () in
bubbleSort(&arr)
}
在这种情况下,闭包的参数被声明为inout
(因此它通过引用传递),以及sortFunc
(在testFunc
中) &#39;类型明确提到它通过引用获取其参数。