You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift可变状态报错:'quantity'为let常量无法修改

问题解决:修改购物车商品数量时报错的处理

错误原因分析

  1. 结构体属性不可变:原Product结构体中所有属性用let声明,属于常量,无法修改。
  2. 值类型副本问题:forEach循环中遍历的product是结构体的值副本,修改副本不会影响原数组中的元素,同时因为原属性是let,所以触发报错。

具体修改步骤

1. 修改Product结构体属性为可变

将Product中所有需要修改的属性从let改为var:

import Foundation
// MARK: - Welcome
struct ProductData: Codable, Hashable {
    let carts: [Cart]
}

// MARK: - Cart
struct Cart: Codable, Hashable {
    let id: Int
    let products: [Product]
}

// MARK: - Product
struct Product: Codable, Hashable, Identifiable {
    var id: Int
    var title: String
    var price, quantity, total: Int
    var discountPercentage: Double
    var discountedPrice: Int
    var thumbnail: String
}

2. 重写add函数,直接修改原数组元素

放弃forEach循环,改用firstIndex找到目标元素的索引,直接修改原数组中的元素(同时同步更新total和discountedPrice保证数据一致性):

class Order: ObservableObject {
    
    @Published var product = [Product]()
    @Published private(set) var productTotal: Int = 0
    
    func add(item: Product) {
        if let index = product.firstIndex(where: { $0.id == item.id }) {
            // 找到已有商品,增加数量
            product[index].quantity += 1
            // 同步更新total和折扣后价格
            product[index].total = product[index].price * product[index].quantity
            let discountAmount = Double(product[index].total) * product[index].discountPercentage / 100
            product[index].discountedPrice = product[index].total - Int(discountAmount)
        } else {
            // 商品不存在,添加新商品(可根据需求调整初始数量)
            var newItem = item
            newItem.quantity = 1
            newItem.total = newItem.price * newItem.quantity
            let discountAmount = Double(newItem.total) * newItem.discountPercentage / 100
            newItem.discountedPrice = newItem.total - Int(discountAmount)
            product.append(newItem)
        }
        // 更新购物车总金额
        productTotal = product.reduce(0) { $0 + $1.discountedPrice }
    }
}

关键说明

  • 结构体是值类型,遍历过程中得到的是元素副本,必须通过索引直接操作原数组才能生效。
  • mutating关键字仅适用于结构体的方法,Order是类,不需要添加该关键字。
  • 同步更新total和discountedPrice是为了保证数据一致性,避免出现数量和金额不匹配的情况。

内容的提问来源于stack exchange,提问作者user21666271

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 06:23:24