Swift结构突变变量不起作用?

Vis*_*l16 1 struct ios swift mutating-function swift4

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

所以基本上我都包裹着我的问题,在一个非常简单的方法,我有一个类Car,拥有3个变量idstartmodelNo

之后,初始化一个空的Car模型数组,然后显示10个汽车,为迭代创建一个范围范围1...10,初始化Car模型类,并将其附加到原始的cars数组中。

前5个汽车ID为0,最后5个汽车ID为1的支票

我想要一个将在其中启动相同ID的最后一辆车的过滤器,因此我创建了一个过滤并修改start变量但无法修改的方法。您能帮我做错什么吗?

请查看我的完整代码,然后将其复制粘贴到操场上。

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()
Run Code Online (Sandbox Code Playgroud)

任何帮助将不胜感激。

Pau*_*w11 5

创建一个 mutating在结构上函数不会更改结构的值语义。一旦struct实例发生突变,就会创建一个副本。

你说:

if var lastItem = filteredItems.last {
    print("Will start \(lastItem.modelNo)")
    lastItem.startCar(status: true)
}
Run Code Online (Sandbox Code Playgroud)

因此,lastItem包含要启动的汽车的实例。在幕后,这是与的汽车相同的实例,也与的汽车filteredItems是相同的实例arrCars。但是,一旦您对Carin进行lastItem了突变,便会创建一个副本,因此lastItem 不再具有与in中的实例相同的实例arrCarsfilteredItems并且arrCars仍然包含原始的,未更改的Car实例。

您可以更改Car为a class而不是astruct以便它具有引用语义以获得所需的行为。

另一个选择是修改实例。像arrCars[0].startCar(status: true)。为此,您需要获得一个数组,其中包含要启动的汽车的索引,而不是汽车本身:

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)
}
Run Code Online (Sandbox Code Playgroud)

但是,在模型对象需要可变性或有状态的情况下,结构可能不合适。