问题描述
即使在方法中使用mutating func
关键字,我也无法修改模型类变量吗?
I am not able to modify my model class variable even using mutating func
keyword in a method?
所以基本上我以一种非常简单的方式包装了我的问题,我有一个具有3个变量id
,start
和modelNo
So basically I have wrapped my problem in a very easy way I have a class Car
that has 3 variable id
, start
, and modelNo
在那之后初始化一个空的Car模型数组,然后我想显示10辆汽车,为迭代1...10
创建一个循环范围,初始化Car模型类并将其附加到原始的cars数组.
After that initialize an empty Car model array and then I want to show 10 cars, creating a range for loop which iterates 1...10
, initializing the Car model class and appending it to original cars array.
有一张检查,前5个汽车ID为0,后5个汽车ID为1
There is a check for first 5 cars id will be 0 and last 5 cars id will be 1
我想要一个过滤器,其中相同id的最后一辆车将在该过滤器中启动,因此我创建了一个过滤的方法,并修改了start变量,但无法对其进行修改.您能帮我做错什么吗?
I want a filter in which same id's last car will start so I have created a method filtered and modifying the start variable but not able to modify it. Can you please help me what I am doing wrong?
请查看我的完整代码,然后将其复制粘贴到操场上.
Please see my complete code and copy paste it to the playground.
struct Car {
var id = 0
var start = false
var modelNo: String
init(start: Bool, id: Int, model: String) {
self.start = start
self.id = id
self.modelNo = model
}
mutating func startCar(status: Bool) {
start = status
}
}
var arrCars:[Car] = [Car]()
for i in 1...10 {
let md = Car(start: false, id: i <= 5 ? 0 : 1, model: "Model\(i)")
arrCars.append(md)
}
private func filtered() {
for item in arrCars {
let filteredItems = arrCars.filter { $0.id == item.id }
if filteredItems.count > 0 {
if var lastItem = filteredItems.last {
print("Will start \(lastItem.modelNo)")
lastItem.startCar(status: true)
}
}
}
let cars = arrCars.filter { (car) -> Bool in
car.start == true
}
print(cars.count)
}
filtered()
任何帮助将不胜感激.
推荐答案
在结构上创建mutating
函数不会更改结构的值语义.一旦结构实例发生突变,就会创建一个副本.
Creating a mutating
function on a struct doesn't change the value semantics of structs. As soon as a struct instance is mutated, a copy is made.
您说:
if var lastItem = filteredItems.last {
print("Will start \(lastItem.modelNo)")
lastItem.startCar(status: true)
}
因此,lastItem
包含您要启动的汽车的实例.在幕后,这是filteredItems
中汽车的相同实例,而在arrCars
中汽车的相同实例.但是,一旦您更改了lastItem
中的Car
,就会创建一个副本,因此lastItem
不再具有与arrCars
中的实例相同的实例. filteredItems
和arrCars
仍然包含原始的,未更改的Car
实例.
So, lastItem
contains an instance of a car you are going to start. Under the covers this is the same instance of the car that is in filteredItems
, which is the same instance that is in arrCars
. But, as soon as you mutate the Car
in lastItem
, a copy is made, so lastItem
no longer has the same instance as the one in arrCars
. filteredItems
and arrCars
still contain the original, unaltered Car
instance.
您可以将Car
更改为class
而不是struct
,以便它具有引用语义以获得所需的行为.
You can change Car
to be a class
rather than a struct
so that it has reference semantics to get the behaviour you want.
另一个选择是修改实例;类似于arrCars[0].startCar(status: true)
.为此,您需要获取一个数组,其中包含要启动的汽车的指标,而不是汽车本身:
The other option is to modify the instance in place; something like arrCars[0].startCar(status: true)
. To do this you will need to get an array containing the indicies of the cars you want to start rather than the cars themselves:
private func filtered() {
for item in arrCars {
let matchingIndices = arrCars.enumerated().compactMap { (index,car) in
return car.id == item.id ? index:nil
}
if matchingIndices.count > 0 {
if let lastIndex = matchingIndices.last {
print("Will start \(arrCars[lastIndex].modelNo)")
arrCars[lastIndex].startCar(status: true)
}
}
}
let cars = arrCars.filter { (car) -> Bool in
car.start == true
}
print(cars.count)
}
但是,在模型对象需要可变性或有状态的情况下,结构可能不合适.
However, where a model object requires mutability or is stateful, a struct is probably not suitable.
这篇关于Swift结构突变变量不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!