当前位置: 首页 > 面试题库 >

golang反映获取闭包函数指针

缪嘉志
2023-03-14
问题内容

请检查代码

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:它们表示调用它们时要执行的同一代码块。

由存储在factory变量中的函数值返回的函数值是一个闭包。只要可访问,它所引用的环境(局部变量和函数参数)就可以保留。在您的情况下,这意味着由于in中的函数值f1f2引用name了封闭的匿名函数的参数,因此只要可访问函数值(in
f1f2),就将保留它们(“ they”(来自多个调用))。这是使它们“不同”或唯一的唯一原因,但从“外部”看不到。

您会继续打印并name在闭包中打印地址吗,您会发现它们对于闭包的多个值而言是不同的变量, 但是 如果再次调用 相同的
闭包(函数值),则它们是 相同 的。首先修改闭包以同时打印以下地址: __name

factory := func(name string) func() {
    return func() {
        fmt.Println(name, &name)
    }
}

并调用f1f2多次:

f1()
f2()
f1()
f2()

输出:

f1 0x1040a120
f2 0x1040a130
f1 0x1040a120
f2 0x1040a130

如您所见,如果再次调用相同的闭包,name则保留该name参数,并再次使用相同的参数。



 类似资料:
  • 闭包是一个特殊的匿名函数,它是匿名函数和相关引用环境组成的一个整体 也就是说只要匿名函数中用到了外界的变量,那么这个匿名函数就是一个闭包 package main import "fmt" func main() { num := 10 a := func() { num++ // 在闭包中用到了main函数中的num, 所以这个匿名函数就是一个闭包

  • 闭包(closure)在 Rust 中也称为 lambda,是一类捕获封闭环境的函数。例如,一个可以捕获 x 变量的闭包如下: |val| val + x 它们的语法和能力使它们在临时(on the fly)使用相当方便。调用一个闭包和调用一个函数完全相同。然而,输入和返回类型两者都可以自动推导,且输入变量名必须指明。 其他的特点包括: 使用 || 替代 () 将输入变量括起来。 区块定界符({}

  • 问题内容: 有没有一种方法可以使用Go中的反射库将类型的名称转换为类型的表示形式? 我有一个库,用户需要为某些代码生成提供类型表示。我知道这一定是有可能的,因为它们只能创建该类型的变量并调用TypeOf函数,但是有没有一种方法可以避免这种情况并仅从名称中获取表示形式? 问题答案: 这个问题不是很明确,可以用两种方式解释,一种是不可能的,另一种是不可能的。另一个答案是肯定的,这是可能的。 在运行时

  • 主要内容:Python闭包的__closure__属性前面章节中,已经对 Python 闭包做了初步的讲解,本节将详解介绍到底什么是闭包,以及使用闭包有哪些好处。 闭包,又称闭包函数或者闭合函数,其实和前面讲的嵌套函数类似,不同之处在于,闭包中外部函数返回的不是一个具体的值,而是一个函数。一般情况下,返回的函数会赋值给一个变量,这个变量可以在后面被继续执行调用。 例如,计算一个数的 n 次幂,用闭包可以写成下面的代码: 运行结果为: 4 8 在上面程

  • 5.4* 闭包函数 自 Vim8,进一步扩展与完善了函数引用的概念,并增加了对闭包与 lambda 表达式的支 持。请用 :version 命令确认编译版本有 +lambda 特性支持。 闭包函数定义 学习 Vim 新功能,在线帮助文档是最佳资料。查阅 Vim8 的 :help :function,可发 现在定义函数时,除了原有的几个属性 range abort dict 外,还多了一个 clos

  • Go支持匿名函数,匿名函数可以形成闭包。闭包函数可以访问定义闭包的函数定义的内部变量。 示例1: package main import "fmt" // 这个"intSeq"函数返回另外一个在intSeq内部定义的匿名函数, // 这个返回的匿名函数包住了变量i,从而形成了一个闭包 func intSeq() func() int { i := 0 return func() i