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

为何Go中返回的闭包函数未获取到唯一指针?

Go闭包函数指针值相同的原因解析

相关Go代码

func creator(v string) func() string {
    return func() string {
        return v
    }
}

func getters(runID string) []func() string {
    return []func() string{
        creator(runID),
    }
}

func TestPtrs(t *testing.T) {
    var allVals []func() string
    for i := 0; i < 20; i++ {
        vals := getters(fmt.Sprintf("run-%d", i))
        for j := range vals {
            fmt.Printf("[%d] Valueof %v pointer: %d\n", i, reflect.ValueOf(vals[j]), reflect.ValueOf(vals[j]).Pointer())
        }
        allVals = append(allVals, vals...)
    }

    for i := range allVals {
        fmt.Printf("[%d] %s\n", i, allVals[i]()) // Works as expected
    }
}

问题

在该场景中,creator函数返回的匿名函数虽代码体相似,但因依赖闭包值v,本质上彼此不同。然而为何这些函数仍返回相同的指针值?

解答

这是因为在Go语言中,闭包的函数指针指向的是其代码段的内存地址,而非闭包实例本身。

你定义的这些匿名函数核心逻辑完全一致——都是返回捕获的变量v,所以它们的代码段在编译后是同一块内存区域。reflect.ValueOf(...).Pointer()方法获取的正是这段执行代码的入口地址,因此所有闭包的这个指针值都会相同。

但要明确:这些闭包实例本身是完全独立的,它们各自持有不同的v值(从测试最后打印的run-0到run-19结果就能验证这一点)。Pointer()方法在这里并没有返回闭包实例的地址,而是函数逻辑的代码位置,这就是指针值相同的核心原因。

简单总结:函数指针代表的是"执行逻辑的代码位置",闭包的差异体现在它们捕获的变量上,而非代码本身。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 04:30:04