Swift:为什么三元运算符会创建数组的副本而不是引用原始数据?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Swift:为什么三元运算符会创建数组的副本而不是引用原始数据?相关的知识,希望对你有一定的参考价值。

我刚刚注意到在使用Swift的三元运算符时我没有想到的一些行为。我有两个数组,根据条件,我想附加到一个或另一个。但是它不会附加到我的类级数组,而只是附加到本地副本。

我假设因为我使用的是自定义类对象的数组,所以它会引用它们而不是创建副本。

示例场景:

class MyViewController: UIViewController {
    var maleArray: [Person] = []
    var femaleArray: [Person] = []

    func append(person: Person) {
        var arrayToAppendTo = person.isMale ? maleArray : femaleArray
        arrayToAppendTo.append(person)
    }
}

在对append(person:)的调用结束时,arrayToAppendTo的计数为1,但maleArrayfemaleArray都是空的。

任何人都可以解释为什么会这样吗?

注意:我知道我可以做一个if/else追加,但我很想知道为什么会出现这种情况。

答案

Swift数组是值类型,因此每次都会生成一个新副本。如果您仍想使用三元运算符,请将其更改为:

person.isMale ? maleArray.append(person) : femaleArray.append(person)
另一答案

正如@ luk2302所述,数组是value types(它们是结构 - 请参阅其docs,它表示它是通用结构,所有结构都是值类型)。这只是意味着如果你创建一个现有数组的“引用”,它将被复制 - 然后如果追加/删除,或者使用新变量修改数组,则不会对原始数组进行修改。

它与三元运算符无关。您可以通过更改来测试它:

var arrayToAppendTo = person.isMale ? maleArray : femaleArray

var arrayToAppendTo = maleArray

你会发现它仍然不会修改属性中的原始数组。

总而言之,您将无法使用中间变量,并且您必须直接访问要更改的阵列。

要么使用@MehulParmar建议的解决方案,要么只使用if-else

if person.isMale {
    maleArray.append(person)
} else {
    femaleArray.append(person)
}

以上是关于Swift:为什么三元运算符会创建数组的副本而不是引用原始数据?的主要内容,如果未能解决你的问题,请参考以下文章

Swift 计算属性返回底层数组的副本

在 .NET 中,使用“foreach”迭代 IEnumerable<ValueType> 的实例会创建一个副本吗?那么我应该更喜欢使用“for”而不是“foreach”吗?

enumerate 是不是会创建其参数的副本?

将数据从 hdfs 导入到 hbase 是不是会创建一个副本

Swift将对象添加到数组会追加副本而不是引用? [复制]

std::vector 的 push_back 是不是会创建参数的深层副本?