Golang 实现获取当前函数名称和文件行号等操作


Posted in Golang onMay 08, 2021

大家还是直接看代码吧~

// 获取正在运行的函数名
func runFuncName()string{
    pc := make([]uintptr,1)
    runtime.Callers(2,pc)
    f := runtime.FuncForPC(pc[0])
    return f.Name()
}
package main 
import(
    "fmt"
    "runtime"
)
 
// 获取正在运行的函数名
func runFuncName()string{
    pc := make([]uintptr,1)
    runtime.Callers(2,pc)
    f := runtime.FuncForPC(pc[0])
    return f.Name()
}
 
func test1(){
    i:=0
    fmt.Println("i =",i)
    fmt.Println("FuncName1 =",runFuncName())
}
 
func test2(){
    i:=1
    fmt.Println("i =",i)
    fmt.Println("FuncName2 =",runFuncName())
}
 
func main(){
    fmt.Println("打印运行中的函数名")
    test1()
    test2()
}

golang 的runtime库,提供Caller函数,可以返回运行时正在执行的文件名和行号:

func Caller(skip int) (pc uintptr, file string, line int, ok bool) {

Caller reports file and line number information about function invocations on the calling goroutine's stack. The argument skip is the number of stack frames to ascend, with 0 identifying the caller of Caller. (For historical reasons the meaning of skip differs between Caller and Callers.) The return values report the program counter, file name, and line number within the file of the corresponding call. The boolean ok is false if it was not possible to recover the information.

调用方法如下,返回的file为绝对路径,line为行号。有了这个就可以在自己的日志等函数中添加这个记录了。

_, file, line, ok := runtime.Caller(1)

补充:go 定位函数操作位置(文件名、函数名、所在行)

runtime.Caller()返回函数执行程序计数pc、执行的文件名和所在行数

runtime.FuncForPC()传入pc,得到运行的函数指针

文件结构

- runtime
- -file1.go
- -file2.go
- -main.go

main.go文件

package main
import (
	"fmt"
	"path"
	"runtime"
)
func main(){
	name, funcName, line := f2(0)
	fmt.Printf("file:%v;function:%v;line:%d",name,funcName,line)
}
func getLocation(skip int)(fileName ,funcName string ,line int){
	pc, file, line, ok := runtime.Caller(skip)
	if !ok {
		fmt.Println("get info failed")
		return
	}
	fmt.Println(pc,file)
	fileName = path.Base(file)
	funcName = runtime.FuncForPC(pc).Name()
	return
}

file1.go文件

package main
func f1(skip int)(fileName ,funcName string ,line int){
 fileName, funcName, line = getLocation(skip)
 return
}

file2.go文件

package main
func f2(skip int)(fileName ,funcName string ,line int){
 return f1(skip)
}

当在main.go文件中调用f2时

func main(){
 name, funcName, line := f2(3)
 fmt.Printf("file:%v;function:%v;line:%d",name,funcName,line)
 //output:file:main.go;function:main.main;line:10
}

f2调取f1,f1调取getLocation;f2->f1->getLocation经历了三层调用,所以在f2中传入3时,返回的当前该函数的执行位置及所在函数名、所在文件名

当传入2时,返回的是(file:file2.go;function:main.f2;line:8)f2函数所在函数名、文件位置、文件名

当传入1时,返回的是(file:file1.go;function:main.f1;line:4)f1函数所在函数名、文件位置、文件名

当传入0时,返回的是(file:main.go;function:main.getLocation;line:16)getLocation函数所在函数名、文件位置、文件名

以上为个人经验,希望能给大家一个参考,也希望大家多多支持三水点靠木。如有错误或未考虑完全的地方,望不吝赐教。

Golang 相关文章推荐
Go语言-为什么返回值为接口类型,却返回结构体
Apr 24 Golang
golang中的空slice案例
Apr 27 Golang
golang 如何通过反射创建新对象
Apr 28 Golang
Golang 如何实现函数的任意类型传参
Apr 29 Golang
解决go在函数退出后子协程的退出问题
Apr 30 Golang
Goland使用Go Modules创建/管理项目的操作
May 06 Golang
Go 在 MongoDB 中常用查询与修改的操作
May 07 Golang
修改并编译golang源码的操作步骤
Jul 25 Golang
golang三种设计模式之简单工厂、方法工厂和抽象工厂
Apr 10 Golang
Golang 1.18 多模块Multi-Module工作区模式的新特性
Apr 11 Golang
Go gorilla securecookie库的安装使用详解
Aug 14 Golang
Golang 获取文件md5校验的方法以及效率对比
May 08 #Golang
GoLang中生成UUID唯一标识的实现
May 08 #Golang
聊聊golang中多个defer的执行顺序
May 08 #Golang
Golang全局变量加锁的问题解决
golang 实现并发求和
May 08 #Golang
golang中的并发和并行
May 08 #Golang
关于golang高并发的实现与注意事项说明
May 08 #Golang
You might like
discuz程序的PHP加密函数原理分析
2011/08/05 PHP
PHP设置图片文件上传大小的具体实现方法
2013/10/11 PHP
PHP简单数据库操作类实例【支持增删改查及链式操作】
2016/10/10 PHP
php源码之将图片转化为data/base64数据流实例详解
2016/11/27 PHP
利用jQuery的deferred对象实现异步按顺序加载JS文件
2013/03/17 Javascript
Jquery仿淘宝京东多条件筛选可自行结合ajax加载示例
2013/08/28 Javascript
Bootstrap每天必学之媒体对象
2015/11/30 Javascript
浏览器兼容的JS写法总结
2016/04/27 Javascript
浅谈js中字符和数组一些基本算法题
2016/08/15 Javascript
完美的js div拖拽实例代码
2016/09/24 Javascript
如何使用Bootstrap创建表单
2017/03/29 Javascript
使用async-validator编写Form组件的方法
2018/01/10 Javascript
详解npm 配置项registry修改为淘宝镜像
2018/09/07 Javascript
微信小程序实现banner图轮播效果
2020/06/28 Javascript
解决Vue中使用keepAlive不缓存问题
2020/08/04 Javascript
three.js着色器材质的内置变量示例详解
2020/08/16 Javascript
[10:54]Team Spirit vs Navi
2018/06/07 DOTA
python之yield表达式学习
2014/09/02 Python
用C++封装MySQL的API的教程
2015/05/06 Python
Python操作列表之List.insert()方法的使用
2015/05/20 Python
python计算auc指标实例
2017/07/13 Python
TensorFlow神经网络优化策略学习
2018/03/09 Python
tensorflow的计算图总结
2020/01/12 Python
python安装和pycharm环境搭建设置方法
2020/05/27 Python
通用的Django注册功能模块实现方法
2021/02/05 Python
使用CSS3的box-sizing属性解决div宽高被内边距撑开的问题
2016/06/28 HTML / CSS
css3的动画特效之动画序列(animation)
2017/12/22 HTML / CSS
前端canvas动画如何转成mp4视频的方法
2019/06/17 HTML / CSS
旅游项目开发策划书
2014/01/18 职场文书
高中军训感言200字
2014/02/23 职场文书
房屋租赁合同协议书范本
2014/10/19 职场文书
幼师辞职信范文
2015/02/27 职场文书
建议书的格式及范文
2015/09/14 职场文书
MySQL对数据表已有表进行分区表的实现
2021/11/01 MySQL
日本动漫十大公认神作:第五现已全网禁播,《死亡笔记》在榜
2022/03/18 日漫
JavaScript实现简单的音乐播放器
2022/08/14 Javascript