请检查代码
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()
}
Run Code Online (Sandbox Code Playgroud)
结果:
4199328 4199328
true
f1
f2
Run Code Online (Sandbox Code Playgroud)
为什么到了闭包函数的同一个地址!或者如何获得唯一地址?
函数指针表示函数的代码。并且函数字面量创建的匿名函数的代码只在内存中存储一次,无论返回匿名函数值的代码运行多少次。这意味着所有函数值(或更准确地说是函数指针)都将相同。
所以你无法区分存储在f1and 中的值f2:它们表示在调用它们时要执行的相同代码块。
存储在factory变量中的函数值返回的函数值是一个闭包。只要它可以访问,它所引用的环境(局部变量和函数参数)就会一直存在。在您的情况下,这意味着由于函数值 inf1和f2引用name封闭匿名函数的参数,只要函数值( inf1和f2)可访问,它们(来自多个调用的“它们”)将被保留。这是唯一使它们“不同”或独特的东西,但这是从“外部”看不到的。
你会继续打印name闭包中的地址吗,你会看到它们是闭包的多个值的不同变量,但是如果再次调用相同的闭包(函数值),它是相同的。首先修改闭包以打印以下地址:name
factory := func(name string) func() {
return func() {
fmt.Println(name, &name)
}
}
Run Code Online (Sandbox Code Playgroud)
并调用f1和f2多次:
f1()
f2()
f1()
f2()
Run Code Online (Sandbox Code Playgroud)
输出:
f1 0x1040a120
f2 0x1040a130
f1 0x1040a120
f2 0x1040a130
Run Code Online (Sandbox Code Playgroud)
如您所见,如果再次调用相同的闭包,name则保留name参数并再次使用相同的参数。
https://golang.org/pkg/reflect/#Value.Pointer
如果 v 的 Kind 是 Func,则返回的指针是底层代码指针,但不一定足以唯一标识单个函数。唯一的保证是当且仅当 v 是一个 nil func 值时结果为零。
| 归档时间: |
|
| 查看次数: |
1886 次 |
| 最近记录: |