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

Go语言中如何为递归函数实现独立有效的缓存装饰器?

解决递归函数装饰器缓存不生效的问题

问题核心是:递归函数fib内部调用的是全局作用域的原函数,而非被装饰后的版本,导致只有最外层调用被缓存,递归过程的结果没被存入缓存,缓存长度远低于预期。

以下是两种可行的解决方案:

方案1:修改全局作用域的函数引用

直接在main函数中把被装饰后的fib赋值给全局变量,让递归调用指向装饰后的函数,缓存即可正常收集所有递归过程的结果。

cache = {}

def cached(func):
    def wrapper(n):
        if n not in cache:
            cache[n] = func(n)
        return cache[n]
    return wrapper

def fib(n):
    if n <= 1:
        return n
    return fib(n-1) + fib(n-2)

def main():
    global fib
    fib = cached(fib)
    print(f"fib(40) = {fib(40)}")
    print(f"缓存长度: {len(cache)}")  # 输出41,符合预期

if __name__ == "__main__":
    main()

方案2:用可变对象存储函数引用(不修改全局变量)

如果不想改动全局的fib函数,可以用一个可变对象(比如列表)来保存fib的引用,让函数内部调用这个可变对象里的函数,后续将装饰后的函数赋值给该对象即可。

cache = {}

def cached(func):
    def wrapper(n):
        if n not in cache:
            cache[n] = func(n)
        return cache[n]
    return wrapper

# 用列表存储函数引用,方便后续更新
fib_func = [None]

def fib(n):
    if n <= 1:
        return n
    # 调用可变对象中存储的函数
    return fib_func[0](n-1) + fib_func[0](n-2)

# 初始化引用为原fib函数
fib_func[0] = fib

def main():
    cached_fib = cached(fib_func[0])
    # 更新引用为装饰后的函数
    fib_func[0] = cached_fib
    print(f"fib(40) = {cached_fib(40)}")
    print(f"缓存长度: {len(cache)}")  # 输出41,符合预期

if __name__ == "__main__":
    main()

方案对比

  • 方案1实现简单,适合不需要保留原fib函数的场景,修改全局变量后,所有地方调用的都是装饰后的版本。
  • 方案2更灵活,不会污染全局作用域,原fib函数依然可以被单独调用,适合需要同时保留两个版本的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 20:48:45