Swift结构突变变量不起作用? [英] Swift struct mutating a variable not working?

查看:88
本文介绍了Swift结构突变变量不起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

即使在方法中使用mutating func关键字,我也无法修改模型类变量吗?

I am not able to modify my model class variable even using mutating func keyword in a method?

所以基本上我以一种非常简单的方式包装了我的问题,我有一个具有3个变量idstartmodelNo

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 中的实例相同的实例. filteredItemsarrCars仍然包含原始的,未更改的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结构突变变量不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆