Swift iOS-为什么我可以循环通过类对象数组并进行属性更改,但不能进行结构更改

Swift iOS-为什么我可以循环通过类对象数组并进行属性更改,但不能进行结构更改,swift,class,struct,Swift,Class,Struct,如果我在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: "Nort

如果我在
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
s是值类型,因此对struct的任何属性进行变异也会对struct实例本身进行变异,
map
中的闭包输入参数是不可变的。因此,当您尝试在
map
的闭包中变异属性
$0
时,您正在尝试变异
$0
本身,以防对值类型集合调用
map

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

您的问题的解决方案是在
映射
中创建结构实例的可变副本,修改其
名称
属性并返回该属性。有两种解决方案,如果您的类型上有少量属性,那么调用它的memberwise初始值设定项就更容易了,但是如果您有很多属性,并且只想改变一些,那么复制结构然后修改必要的属性是更好的选择

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分钟内无法投票,请稍等。
让transformed=countryArr.index.map{countryArr[$0].name=“Random”}
也应该work@E.Coms如果
countryArr
是可变的,那么它确实可以工作,但是其他两个解决方案也可以工作,即使数组本身是不可变的。即使属性本身是不可变的,第一种解决方案也会起作用。@DávidPásztor因此在结构上使用.map{$0}实际上会尝试更改原始结构的内存地址,还是尝试在新内存地址创建新结构?@LanceSamaria您的示例实际上不会编译,正如我在回答中所说的,闭包输入参数是不可变的。正如我已经说过的,结构是值类型,因此更改结构属性也会更改结构实例本身
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
}