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 相关文章推荐
golang interface判断为空nil的实现代码
Apr 24 Golang
Golang 实现超大文件读取的两种方法
Apr 27 Golang
golang http使用踩过的坑与填坑指南
Apr 27 Golang
golang日志包logger的用法详解
May 05 Golang
Go timer如何调度
Jun 09 Golang
Go遍历struct,map,slice的实现
Jun 13 Golang
Go 通过结构struct实现接口interface的问题
Oct 05 Golang
深入理解go缓存库freecache的使用
Feb 15 Golang
Golang原生rpc(rpc服务端源码解读)
Apr 07 Golang
golang的文件创建及读写操作
Apr 14 Golang
Golang 切片(Slice)实现增删改查
Apr 22 Golang
Golang 并发编程 SingleFlight模式
Apr 26 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
php数组应用之比较两个时间的相减排序
2008/08/18 PHP
php实现每天自动变换随机问候语的方法
2015/05/12 PHP
php mysql_list_dbs()函数用法示例
2017/03/29 PHP
PHP实现限制IP访问及提交次数的方法详解
2017/07/17 PHP
用tip解决Ext列宽度不够的问题
2008/12/13 Javascript
ASP.NET jQuery 实例18 通过使用jQuery validation插件校验DropDownList
2012/02/03 Javascript
如何将网页表格内容导入excel
2014/02/18 Javascript
用Jquery.load载入页面后样式没了页面混乱的解决方法
2014/10/20 Javascript
JS实现仿苹果底部任务栏菜单效果代码
2015/08/28 Javascript
JS实现鼠标框选效果完整实例
2016/06/20 Javascript
支持移动端原生js轮播图
2017/02/16 Javascript
微信小程序中顶部导航栏的实现代码
2017/03/30 Javascript
JS实现百度搜索接口及链接功能实例代码
2018/02/02 Javascript
JavaScript反射与依赖注入实例详解
2018/05/29 Javascript
微信小程序onLaunch异步,首页onLoad先执行?
2018/09/20 Javascript
JS使用Prim算法和Kruskal算法实现最小生成树
2019/01/17 Javascript
ES6知识点整理之对象解构赋值应用示例
2019/04/17 Javascript
[01:08:57]2014 DOTA2国际邀请赛中国区预选赛 5 23 CIS VS LGD第二场
2014/05/24 DOTA
[53:36]Liquid vs VP Supermajor决赛 BO 第三场 6.10
2018/07/05 DOTA
[52:06]完美世界DOTA2联赛决赛日 Inki vs LBZS 第一场 11.08
2020/11/10 DOTA
Python正则获取、过滤或者替换HTML标签的方法
2016/01/28 Python
详解Python中open()函数指定文件打开方式的用法
2016/06/04 Python
Python简单操作sqlite3的方法示例
2017/03/22 Python
Python开发SQLite3数据库相关操作详解【连接,查询,插入,更新,删除,关闭等】
2017/07/27 Python
Python语言实现百度语音识别API的使用实例
2017/12/13 Python
Python 通配符删除文件的实例
2018/04/24 Python
Python学习笔记基本数据结构之序列类型list tuple range用法分析
2019/06/08 Python
python 中pyqt5 树节点点击实现多窗口切换问题
2019/07/04 Python
Django分页功能的实现代码详解
2019/07/29 Python
Pandas读取csv时如何设置列名
2020/06/02 Python
HTML5中的强制下载属性download使用实例解析
2016/05/12 HTML / CSS
英国现代、当代和设计师家具店:Furntastic
2020/07/18 全球购物
委托书范本
2014/04/02 职场文书
老公给老婆的保证书
2014/04/28 职场文书
2014年实习生工作总结
2014/11/27 职场文书
对领导班子的意见和建议
2015/06/08 职场文书