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】:这个问题是由于struct
s 是值类型,所以改变结构的任何属性也会改变结构实例本身,并且map
中的闭包输入参数是不可变的。因此,当您尝试在 map
的闭包中更改属性 $0
时,您正在尝试更改 $0
本身,以防在值类型集合上调用 map
。
另一方面,class
es 是引用类型,因此改变 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 - 我为啥可以循环遍历一组类对象并进行属性更改但不能更改结构[重复]的主要内容,如果未能解决你的问题,请参考以下文章
为啥这个 Swift Playground 打印和循环两次?