Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays Swift通用数组';不完全相同';错误_Arrays_Swift_Generics - Fatal编程技术网

Arrays Swift通用数组';不完全相同';错误

Arrays Swift通用数组';不完全相同';错误,arrays,swift,generics,Arrays,Swift,Generics,我只是在看一些迅捷的图坦卡蒙,显然在Beta3已经过时了 func exchange<T>(data:[T], i:Int, j:Int) { let temp = data[i]; data[i] = data[j]; data[j] = temp; } func交换(数据:[T],i:Int,j:Int) { 设温度=数据[i]; 数据[i]=数据[j]; 数据[j]=温度; } 游乐场告诉我: 错误:@lvalue$T8与T不相同 如何更改它以使其工

我只是在看一些迅捷的图坦卡蒙,显然在Beta3已经过时了

func exchange<T>(data:[T], i:Int, j:Int)
{
    let temp = data[i];
    data[i] = data[j];
    data[j] = temp;
}
func交换(数据:[T],i:Int,j:Int)
{
设温度=数据[i];
数据[i]=数据[j];
数据[j]=温度;
}
游乐场告诉我:

错误:@lvalue$T8与T不相同


如何更改它以使其工作?

Swift中的数组是值类型。这意味着
数据
在传递到
交换
方法时会被复制,但您正试图修改副本以影响原始版本。相反,你应该做两件事中的一件:

1.将
data
定义为
inout
参数: 2.返回阵列的副本(推荐)
func交换(数据:[T],i:Int,j:Int)->[T]
{
var newData=data
newData[i]=数据[j]
newData[j]=数据[i]
返回新数据
}

我建议使用这种方法而不是使用in-out参数,因为in-out参数会创建更复杂的状态。有两个变量指向并可能操纵同一块内存。如果
exchange
决定在单独的线程上执行其工作,该怎么办?还有一个原因是苹果决定制作数组值类型,使用in-out subversit。最后,返回一份副本更接近Swift可以采取的一个有希望的方向。我们的应用程序中的状态越少,我们(通常)创建的bug就越少。

感谢您的快速解释,这可能是重复的!两个有用的方法来了解!请您解释一下,为什么不推荐
inout
参数?对于大型数组,这比每次调用该方法时都复制数组更有效…@holex当然,我更新了我的答案。我认为在编写代码时担心效率是不明智的。可理解性和可靠性更为重要,直到您运行仪器并发现该方法是一个巨大的瓶颈。此外,编译器应该能够在适当的时候优化复制。@drewag,我理解你关于可靠性的观点,但是使用
inout
参数是完全可靠的!唯一的弱点是开发人员,但如果开发人员受教育程度低(这会导致较差的实现,导致更多的bug,导致花费更多的时间修复bug等等),不管他们使用哪个版本,他们最终都会在项目中犯逻辑结构错误。然而,我想我们都有不同的调试策略,就我个人而言,我花了10-15%的开发时间来修复bug,但我见过“开发人员”花了60-65%的时间——你知道这意味着什么。@holex认为所有开发人员都不容易出错是天真的。我认为最好是使用技术,尽量减少这种可能性。状态是最容易出错的地方,因为无论你是一个多么优秀的程序员,在你的脑海中都只有那么多的状态可以记录,尤其是在与其他开发人员合作、继承代码库或冒充代码库时。此外,使用复制技术可以轻松地在异步代码中使用相同的技术。尽管如此,出于某种原因,我仍然将
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
}