golang 反射获取闭包函数指针

请检查代码


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

为什么到了闭包函数的同一个地址!或者如何获取唯一地址!


繁华开满天机
浏览 287回答 3
3回答

白衣染霜花

函数指针表示函数的代码。而函数字面量创建的匿名函数的代码只会在内存中存储一次,无论返回匿名函数值的代码运行多少次。这意味着所有函数值(或更准确地说是函数指针)都将相同。所以你无法区分存储在f1and 中的值f2:它们表示在调用它们时要执行的相同代码块。存储在factory变量中的函数值返回的函数值是一个闭包。只要它可以访问,它所引用的环境(局部变量和函数参数)就会一直存在。在您的情况下,这意味着由于函数值 inf1和f2引用name封闭匿名函数的参数,只要函数值( inf1和f2)可访问,它们(来自多个调用的“它们”)将被保留。这是唯一使它们“不同”或独特的东西,但这是从“外部”看不到的。你会继续打印name闭包中的地址吗,你会看到它们是闭包的多个值的不同变量,但是如果再次调用相同的闭包(函数值),它是相同的。首先修改闭包以打印以下地址:namefactory := func(name string) func() {    return func() {        fmt.Println(name, &name)    }}并调用f1和f2多次:f1()f2()f1()f2()输出:f1 0x1040a120f2 0x1040a130f1 0x1040a120f2 0x1040a130如您所见,如果再次调用相同的闭包,name则保留name参数并再次使用相同的参数。

幕布斯7119047

https://golang.org/pkg/reflect/#Value.Pointer如果 v 的 Kind 是 Func,则返回的指针是底层代码指针,但不一定足以唯一标识单个函数。唯一的保证是当且仅当 v 是一个 nil func 值时结果为零。

慕森王

实际上,*func()在 Golang 中输入相当于void (*)(void)在 C 中输入。(我知道这一点是因为我经常使用 cgo。)并且func()在围棋被定义为文字,这意味着它的类似的东西代表机器代码,而不是一个函数指针字节的BLOB。请注意,Golang中一切都是按值传递的,甚至 Go 中的函数也不例外。var f1 func() = ... reflect.ValueOf(f1)当您这样做时,我认为您正在尝试获取名为 的代码块的前 8 个字节f1,这不是该函数的地址。在 Go 中,您永远无法获得 a 的地址func()。因为 afunc()是文字,文字没有地址。文字不在内存中的任何地方。所以你不能得到一个地址。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go