为何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
相关产品推荐
相关产品推荐

