首页 > 解决方案 > Swift iOS - 我为什么可以循环遍历一组类对象并进行属性更改但不能更改结构

问题描述

如果我遍历一个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" }

标签: swiftclassstruct

解决方案


该问题是由 s 是值类型这一事实引起的struct,因此改变结构的任何属性也会改变结构实例本身,并且闭包输入参数map是不可变的。因此,当您尝试$0在 的闭包中改变属性时map,您是在尝试改变$0自身,以防map在值类型的集合上被调用。

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

您的问题的解决方案是在 中创建 struct 实例的可变副本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
}

推荐阅读