Go语言如何将作为函数参数传入的函数转为字符串用于存储
Go 是静态编译型语言,和能直接通过 toString() 获取函数源码的 JavaScript 不同,Go 二进制运行时默认不保留函数的实现源码,你只能通过标准库接口获取函数的定义名称,无法直接拿到源码文本。
可行实现方案
如果你只需要存储函数的唯一标识,用 runtime + reflect 包获取函数名称即可,修改后的代码如下:
package main import ( "fmt" "reflect" "runtime" ) func describe(i interface{}) string { fnPtr := reflect.ValueOf(i).Pointer() fnMeta := runtime.FuncForPC(fnPtr) if fnMeta == nil { return "unknown_func" } // 也可以通过 fnMeta.FileLine(fnPtr) 拿到函数定义的文件路径和行号 return fnMeta.Name() } func dummyReducer(int) int { return 1 } // 测试用的reducer函数 func sumReducer(a, b int) int { return a + b } func Accumulator(reducer func(int, int) int, init int) func(int) int { input := map[string]interface{}{ "func_name": "accumulatorLoger", "func_data": map[string]interface{}{ "reducer": describe(reducer), "init": init, }, } // 输出示例:map[func_data:map[init:10 reducer:main.sumReducer] func_name:accumulatorLoger] fmt.Println(input) // 后续存储到数据库逻辑 return dummyReducer } func main() { // 测试调用 Accumulator(sumReducer, 10) }
特殊场景说明
- 如果你传入的是匿名函数,
runtime拿到的会是自动生成的函数名(格式类似main.func1),没有明确标识,这种场景建议你为所有需要存储的函数定义显式命名,或者提前为每个函数绑定唯一ID,直接存储ID即可。 - 如果你确实需要存储函数的实现源码,你需要预先维护所有可用 reducer 的名称-源码映射表,或者在编译阶段通过
go generate配合go/ast工具解析源码生成映射文件,嵌入到程序中使用,运行时无法直接拿到源码。
内容的提问来源于stack exchange,提问作者Romel Gomez
相关产品推荐
相关产品推荐

