swift - 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" }
解决方案
该问题是由 s 是值类型这一事实引起的struct
,因此改变结构的任何属性也会改变结构实例本身,并且闭包输入参数map
是不可变的。因此,当您尝试$0
在 的闭包中改变属性时map
,您是在尝试改变$0
自身,以防map
在值类型的集合上被调用。
另一方面,class
es 是引用类型,因此改变实例的属性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
}
推荐阅读
- c# - 如何在 WinForms、C# 中保持选中的已禁用单选按钮
- angular - 如何使用 Angular 9 和 NG_VALUE_ACCESSOR?
- django - 如何在 Django 中输入当前日期和时间?
- vue.js - 如何在向组件传递不同数据的同时多次使用组件?
- c++ - 用于查找二叉树高度的递归代码
- c# - 从 for 循环中断的用户输入
- ruby-on-rails - 在 Rails API 中存储图像并将其传递给 React App?
- php - if语句php中的宾格数组值
- javascript - 如果 Axios.get 响应数据良好,则 React setState
- python - Plotly express 在 Python 中绘制的意外附加线