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

带自定义下标的Swift结构体作为计算属性的递归问题解决

解决方案:打破递归,实现缓存Sum+动态获取其他值

问题核心

原实现的递归死循环源于:计算属性exampleImplementation每次访问都会调用sampleFunc,而sampleFunc又需要获取exampleImplementation["Sum"],这会再次触发计算属性的求值,形成无限递归。

要解决这个问题,关键是拆分逻辑:将Sum的值单独缓存,让sampleFunc直接使用缓存的Sum值,而非通过计算属性获取;同时让非Sum索引的值动态从sampleFunc获取。

具体实现步骤

1. 重构ExampleStruct,支持缓存Sum和动态值提供

调整结构体,让它可以接收缓存的Sum值,以及一个用于获取非Sum值的闭包:

struct ExampleStruct {
    private var cachedSum: Double
    private let valueProvider: (String) -> Double?
    
    // 初始化:传入缓存的Sum,以及获取其他值的闭包
    init(cachedSum: Double, valueProvider: @escaping (String) -> Double?) {
        self.cachedSum = cachedSum
        self.valueProvider = valueProvider
    }
    
    subscript(index: String) -> Double? {
        get {
            if index == "Sum" {
                // 访问Sum时直接返回缓存值
                return cachedSum
            } else {
                // 访问其他索引时,通过闭包动态获取值
                return valueProvider(index)
            }
        }
        set {
            guard let newValue = newValue else { return }
            if index == "Sum" {
                // 设置Sum时直接更新缓存
                cachedSum = newValue
            } else {
                // 设置其他索引时,根据需求更新缓存的Sum
                // 示例逻辑:用旧值和新值的差更新Sum
                let oldValue = valueProvider(index) ?? 0
                cachedSum = cachedSum - oldValue + newValue
            }
        }
    }
}

2. 实现无递归的计算属性exampleImplementation

单独维护缓存的Sum值,让sampleFunc直接使用该缓存值,避免触发计算属性的递归求值:

// 私有存储属性:缓存Sum的值,初始值可根据业务设置
private var cachedSum: Double = 25

var exampleImplementation: ExampleStruct {
    return ExampleStruct(cachedSum: cachedSum) { index in
        // 调用sampleFunc时直接传入缓存的Sum,而非访问exampleImplementation["Sum"]
        let funcResult = sampleFunc(usingSum: cachedSum)
        return funcResult[index]
    }
}

// 调整sampleFunc的签名,接收Sum参数
func sampleFunc(usingSum sum: Double) -> ExampleStruct {
    // 直接使用传入的sum调用sampleFunc2,避免递归
    let sample2Result = sampleFunc2(sum: sum)
    
    // 构建并返回ExampleStruct示例,实际逻辑根据业务调整
    return ExampleStruct(
        cachedSum: sum,
        valueProvider: { key in
            switch key {
            case "Ind1": return sample2Result
            case "Ind2": return 13
            default: return nil
            }
        }
    )
}

func sampleFunc2(sum: Double) -> Double {
    // 示例逻辑:根据Sum计算返回值
    return sum * 0.5
}

关键说明

  • 打破递归:sampleFunc不再依赖exampleImplementation["Sum"],而是直接使用传入的缓存Sum值,彻底切断递归循环。
  • 缓存Sum:Sum的值单独存储,访问时直接返回,无需重复计算或调用外部方法。
  • 动态获取其他值:非Sum索引的值通过闭包动态从sampleFunc获取,保证数据的实时性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 02:13:25