【问题标题】:Swift Generic Array 'not identical' errorSwift Generic Array“不相同”错误
【发布时间】: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 不同。

如何更改它以使其正常工作?

【问题讨论】:

标签: arrays swift generics


【解决方案1】:

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

1。将data定义为inout参数:

func exchange<T>(inout data:[T], i:Int, j:Int)

然后在调用它时你必须在调用之前添加一个&amp;

var myArray = ["first", "second"]
exchange(&myArray, 0, 1)

2。返回数组的副本(推荐)

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参数吗?在巨大数组的情况下,这比每次调用方法时都复制数组更有效...
  • @holex 当然,我更新了我的答案。我认为在编写代码时担心效率是不明智的。在您运行仪器并发现该方法是一个巨大的瓶颈之前,可理解性和可靠性更为重要。此外,编译器应该能够在适当的时候优化复制。
  • @drewag,我理解你关于可靠性的观点,但是使用inout 参数是完全可靠的!唯一的弱点是开发人员,但如果开发人员教育不足(导致实施不佳,导致出现更多错误,导致花费更多时间修复错误等......),他们使用哪个版本无关紧要,他们最终会在项目中犯逻辑结构错误。但是,我想我们都有不同的调试策略,我个人花费了 10-15% 的开发时间来修复错误,但我见过花费 60-65% 的“开发人员”——你知道这意味着什么。
  • @holex 认为所有开发人员都不容易出错是天真的想法。我相信最好使用将这种可能性降至最低的技术。状态是最容易出错的地方,因为无论你是多么优秀的程序员,你可以在脑海中记录的状态只有这么多,尤其是在与其他开发人员合作、继承代码库或冒充他人时代码库。此外,使用复制技术可以让您毫不费力地在异步代码中使用相同的技术。尽管如此,我仍然将inout列为有效解决方案是有原因的。
猜你喜欢
  • 2017-01-03
  • 1970-01-01
  • 2019-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-15
  • 1970-01-01
相关资源
最近更新 更多