【发布时间】:2014-07-16 15:05:25
【问题描述】:
我只是在浏览一些从 Beta3 开始显然已经过时的 Swift tuts ...
func exchange<T>(data:[T], i:Int, j:Int)
{
let temp = data[i];
data[i] = data[j];
data[j] = temp;
}
游乐场告诉我:
错误:@lvalue $T8 与 T 不同。
如何更改它以使其正常工作?
【问题讨论】:
我只是在浏览一些从 Beta3 开始显然已经过时的 Swift tuts ...
func exchange<T>(data:[T], i:Int, j:Int)
{
let temp = data[i];
data[i] = data[j];
data[j] = temp;
}
游乐场告诉我:
错误:@lvalue $T8 与 T 不同。
如何更改它以使其正常工作?
【问题讨论】:
Swift 中的数组是值类型。这意味着 data 在传递到您的 exchange 方法时被复制,但您正在尝试修改副本以影响原始版本。相反,您应该做以下两件事之一:
data定义为inout参数:func exchange<T>(inout data:[T], i:Int, j:Int)
然后在调用它时你必须在调用之前添加一个&:
var myArray = ["first", "second"]
exchange(&myArray, 0, 1)
func exchange<T>(data:[T], i:Int, j:Int) -> [T]
{
var newData = data
newData[i] = data[j]
newData[j] = data[i]
return newData
}
我推荐这种方式而不是 in-out 参数,因为 in-out 参数会创建更复杂的状态。您有两个变量指向并可能操纵同一块内存。如果exchange 决定在单独的线程上工作怎么办?苹果决定制作数组值类型也是有原因的,使用 in-out 颠覆了这一点。最后,返回一个副本更接近于Functional Programming,这是 Swift 可以移动的一个有希望的方向。我们在应用中拥有的状态越少,我们将创建的错误就越少(通常)。
【讨论】:
inout参数吗?在巨大数组的情况下,这比每次调用方法时都复制数组更有效...
inout 参数是完全可靠的!唯一的弱点是开发人员,但如果开发人员教育不足(导致实施不佳,导致出现更多错误,导致花费更多时间修复错误等......),他们使用哪个版本无关紧要,他们最终会在项目中犯逻辑结构错误。但是,我想我们都有不同的调试策略,我个人花费了 10-15% 的开发时间来修复错误,但我见过花费 60-65% 的“开发人员”——你知道这意味着什么。
inout列为有效解决方案是有原因的。