请检查代码
package main import ( "fmt" "reflect" ) func main() { factory := func (name string) func(){ return func (){ fmt.Println(name) } } f1 := factory("f1") f2 := factory("f2") pf1 := reflect.ValueOf(f1) pf2 := reflect.ValueOf(f2) fmt.Println(pf1.Pointer(), pf2.Pointer()) fmt.Println(pf1.Pointer() == pf2.Pointer()) f1() f2() }
结果:
4199328 4199328 true f1 f2
为什么要到达关闭函数的相同地址!或如何获得唯一的地址!
函数指针表示函数的代码。由函数文字创建的匿名函数的代码仅在内存中存储一次,无论返回匿名函数值的代码运行了多少次。这意味着所有函数值(或更确切地说,函数指针)将相同。
因此,您无法区分存储在f1和中的值f2:它们表示调用它们时要执行的同一代码块。
f1
f2
由存储在factory变量中的函数值返回的函数值是一个闭包。只要可访问,它所引用的环境(局部变量和函数参数)就可以保留。在您的情况下,这意味着由于in中的函数值f1并f2引用name了封闭的匿名函数的参数,因此只要可访问函数值(in f1和f2),就将保留它们(“ they”(来自多个调用))。这是使它们“不同”或唯一的唯一原因,但从“外部”看不到。
factory
name
您会继续打印并name在闭包中打印地址吗,您会发现它们对于闭包的多个值而言是不同的变量, 但是 如果再次调用 相同的 闭包(函数值),则它们是 相同 的。首先修改闭包以同时打印以下地址: __name
factory := func(name string) func() { return func() { fmt.Println(name, &name) } }
并调用f1和f2多次:
f1() f2() f1() f2()
输出:
f1 0x1040a120 f2 0x1040a130 f1 0x1040a120 f2 0x1040a130
如您所见,如果再次调用相同的闭包,name则保留该name参数,并再次使用相同的参数。