为何在Go语言中无法直接取函数地址,却可获取函数值的地址?
Go中函数名与函数值变量的区别
先直接给出结论:myFunc和functionValue的类型确实都是func(),但二者本质完全不同,这也是前者不能取地址、后者可以的核心原因。
核心差异
myFunc是函数实体的标识符:它指向编译期就确定的函数代码本身,属于程序的只读代码段。Go语言语法规则直接禁止获取这类函数实体的地址——因为函数实体本身不是可寻址的变量,不存在“存储它的内存地址”这个可操作的概念。functionValue是函数类型的变量:执行functionValue := myFunc时,是把函数实体的引用(函数值)赋值给了一个变量。这个变量存储在栈或堆上,属于可寻址的内存空间,自然可以用&取它的地址。
类型层面的细节
虽然两者对外暴露的类型都是func(),但myFunc是函数类型的字面量,functionValue是函数类型的实例变量。Go允许将函数标识符隐式转换为函数值赋值给变量,但这不代表二者是同一个东西——就像你不能取字面常量5的地址,但可以把5赋值给变量var a int = 5后取&a。
代码验证示例
package main import "fmt" func myFunc() {} func main() { functionValue := myFunc // 打印函数名的类型和值 fmt.Printf("myFunc: 类型=%T,值=%v\n", myFunc, myFunc) // 打印函数值变量的类型和值 fmt.Printf("functionValue: 类型=%T,值=%v\n", functionValue, functionValue) // 打印函数值变量的地址 fmt.Printf("&functionValue: 类型=%T,值=%v\n", &functionValue, &functionValue) }
运行后能看到,myFunc和functionValue的值都是函数的入口地址,但myFunc无法用&获取地址,而functionValue作为变量可以。
内容的提问来源于stack exchange,提问作者zuselegacy
相关产品推荐
相关产品推荐

