Swift iOS - 我为啥可以循环遍历一组类对象并进行属性更改但不能更改结构[重复]

Posted

技术标签:

【中文标题】Swift iOS - 我为啥可以循环遍历一组类对象并进行属性更改但不能更改结构[重复]【英文标题】:Swift iOS -How come I can loop through an array of class objects and make property changes but not structs [duplicate]Swift iOS - 我为什么可以循环遍历一组类对象并进行属性更改但不能更改结构[重复] 【发布时间】:2019-08-06 18:20:29 【问题描述】:

如果我遍历 Class 对象的数组,我可以对其上的属性进行更改

class Country 
    var name: String?
    var region: String?

    init(name: String?, region: String?) 
        self.name = name
        self.region = region
    


let canada = Country(name: "Canada", region: "North America")
let mexico = Country(name: "Mexico", region: "North Ameria")
let france = Country(name: "France", region: "Europe")
let korea = Country(name: "Korea", region: "Asia")

var countryArr = [canada, mexico, france, korea]

// this works fine
let transformed = countryArr.map  $0.name = "Random" 

但如果我用Struct 对象尝试这个,我会得到

无法分配给属性:“$0”是不可变的

struct Country 
    var name: String?
    var region: String?


var canada = Country(name: "Canada", region: "North America")
var mexico = Country(name: "Mexico", region: "North Ameria")
var france = Country(name: "France", region: "Europe")
var korea = Country(name: "Korea", region: "Asia")

var countryArr = [canada, mexico, france, korea]

// this gets an error
let transformed = countryArr.map  $0.name = "Random" 

【问题讨论】:

【参考方案1】:

这个问题是由于structs 是值类型,所以改变结构的任何属性也会改变结构实例本身,并且map 中的闭包输入参数是不可变的。因此,当您尝试在 map 的闭包中更改属性 $0 时,您正在尝试更改 $0 本身,以防在值类型集合上调用 map

另一方面,classes 是引用类型,因此改变 class 实例的属性不会改变实例本身。

您的问题的解决方案是在map 中创建结构实例的可变副本,改变其name 属性并返回它。有两种解决方案,如果你的类型有少量属性,调用它的成员初始化器更容易,但是如果你有很多属性并且只想改变一些,复制结构然后修改必要的属性是更好的选择。

let transformed = countryArr.map  Country(name: "Random", region: $0.region) 
let transformed2 = countryArr.map  country->Country in
    var copy = country
    copy.name = "Random"
    return copy

【讨论】:

您好,感谢您的解释。我不能在 2 分钟内投票,所以请稍等。 let transformed = countryArr.indices.map countryArr[$0].name = "Random" 也应该可以工作 @E.Coms 如果countryArr 是可变的,它确实有效,但即使数组本身是不可变的,其他两种解决方案也有效。如果属性本身是不可变的,第一个解决方案甚至可以工作。 @DávidPásztor 所以在结构上使用 .map $0 实际上会尝试更改原始结构的内存地址,还是会尝试在新的内存地址创建新结构? @LanceSamaria 您的示例实际上不会编译,因为正如我在回答中已经说过的,闭包输入参数是不可变的。正如我已经说过的,结构体是值类型,所以改变结构体属性也会改变结构体实例本身

以上是关于Swift iOS - 我为啥可以循环遍历一组类对象并进行属性更改但不能更改结构[重复]的主要内容,如果未能解决你的问题,请参考以下文章

iOS+Swift:为啥音乐不能在 iPad 上播放?

将一组类对象添加到一个主类对象中

在Java中的包内获取一组类文件[重复]

为啥这个 Swift Playground 打印和循环两次?

Swift - 坐标不可用:从 iOS 7 开始不推荐使用 API

jQuery 获取下一组类?