runtime Caller 方法再封装
在 Go单元测试——资源初始化 里获取配置文件的绝对路径时,提到了 Caller 方法。这个方法在日志打印的包中特别常见。
日志文件中记录的文件路径和行号,就是这个函数的返回值。
pc, file, line, ok := runtime.Caller(0)
翻看一些日志的开源包,可能就会看到这个方法的调用。如果全局没有搜索到的话,很可能是它组合调用了类似下面的自定义方法,想要获取更多的调用栈信息。对比 runtime.Caller
源码和我们自定义的 GetCallerFrame 方法,它们内部实现逻辑是完全一致的,只是返回值上做了处理。
func GetCallerFrame(skip int) runtime.Frame {rpc := make([]uintptr, 1)n := runtime.Callers(skip, rpc[:])if n < 1 {return runtime.Frame{}}frame, _ := runtime.CallersFrames(rpc).Next()return frame
}
通过 runtime.Frame 可以获取到调用栈的方法体信息,通过 frame.Function 我们可以获取很多有用的信息,比如当前调用的函数名、文件的路径、结构体的名称。如果你看过 panic 输出的调用栈信息的话,调用栈信息中显示的函数就是 frame.Function 。
我们将GetCallerFrame作为一个util类的方法,然后来实际说明一下.。其中,GetHistory中会调用util中的 GetCallerFrame 方法,我们看一下它的具体实现:
live.go 的代码如下,特别说明的是,目录的名称和包的声明不相同,目录名称为data,包名为dataPackage,主要是区分,caller最终输出的是目录的路径,而非包名。
函数体中skip传递 2 表示获取的是GetHistory的方法信息,递推的向上,0代表Caller本身,1代表封装它的函数GetCallerFrame,2就代表当前调用GetCallerFrame的函数。
执行结果输出:路径+结构体+方法名称,通过这个输出,我们可以提炼获取方法名称的函数:
local/awesomeProject3/data.(*Live).GetHistory
如果要变得更加通用一些,方法体中的常量2其实可以声明为 skip + 1,我们把 GetCallerFrame 当做我们代码意义上的 “Caller”。
// desc: 获取方法名称
func GetCallerFunction(skip ...int) string {s := 0if len(skip) != 0 {s = skip[0]}frame := GetCallerFrame(s + 1)function := ""if split := strings.LastIndexByte(frame.Function, '/'); split != -1 && split+1 < len(frame.Function) {function = frame.Function[split+1:]}if split := strings.IndexByte(function, '.'); split != -1 && split+1 < len(function) {function = function[split+1:]}return function
}
类似于获取路径、行号的就都很简单了
runtime Caller 方法再封装相关推荐
- 不要再封装各种Util工具类了,这个神级框架值得拥有!
点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! Hutool 谐音 "糊涂",寓意追求 ...
- iOS经典面试题之使用runtime associate方法关联的对象释放及dealloc底层原理
一.题目分析 使用 runtime associate 方法关联的对象,需要在主对象 dealloc 的时候释放吗? 无论在 MRC 下还是 ARC 下均不需要,被关联的对象在生命周期内要比对象本身释 ...
- 加密封装 怎么把_不要再封装各种Util工具类了,这个神级框架值得拥有!
Hutool 谐音 "糊涂",寓意追求 "万事都作糊涂观,无所谓失,无所谓得" 的境界. Hutool 是一个 Java 工具包,也只是一个工具包,它帮助我们简 ...
- httpurlconnection 封装_不要再封装各种Util工具类了,看看这个框架
不要再封装各种Util工具类了,看看这个框架 Hutool 谐音 "糊涂",寓意追求 "万事都作糊涂观,无所谓失,无所谓得" 的境界. Hutool 是一 ...
- Go学习——runtime.Caller()函数
目录 函数: 参数解释: 例子: 函数: func Caller(skip int) (pc uintptr, file string, line int, ok bool) Caller()报告当前 ...
- golang runtime.Caller 学习笔记
runtime.Caller runtime.Caller可以获取到调用时的代码文件路径.行数等信息,在打印日志时常常使用 runtime.Caller源码 // Caller reports fil ...
- java exec 路径_[Java] 关于java.lang.Runtime.exec()方法运行命令所在目录的探讨。 | 学步园...
测试代码: import java.util.*; import java.io.*; publicclassBadExecJavac { publicstaticvoidmain(String ar ...
- Promise方法 理解 封装
Promise是什么? Promise直接打印出来看看吧,console.dir(Promise),就这么简单粗暴 可以看出:Promise是一个构造函数.ES6中新增的. 从打印的结果可以看出 里面 ...
- 【类库】私房干货.Net数据层方法的封装
[类库]私房干货.Net数据层方法的封装 作者:白宁超 时间:2016年3月5日22:51:47 摘要:继上篇<Oracle手边常用70则脚本知识汇总>文章的发表,引起很多朋友关注.便促使 ...
最新文章
- 衡量微型计算机的性能指标参数有哪些,衡量计算机性能的主要技术指标有哪些?...
- 区块链公司发现BCH团队比BTC团队更容易接近
- 问题小结(2)-dialog内容动态变化(调用系统方法时)
- 分布式中的 transaction log
- 计算从A地出发到各个地方的路径及距离
- php eot eod_EOD的完整形式是什么?
- 【英语学习】【Level 08】U05 Better option L5 A picture is worth a thousand words
- php面向对象受保护,php面向对象二之封装,protected ,public,private权限管理
- 扫地机器人单扫和双扫_评测 | 千元以下的扫拖一体机器人,到底值不值得买?...
- 惨遭打脸:字节某部门竟然有这么多测试
- CentOS6.5 firefox安装flash插件
- HBASE元数据及数据读取过程
- 第十二课,assimp模型加载(数据加载篇)
- 错误记录(Unindent amount does not match previous indent)
- 直播活动策划方案怎么做
- 服务器电脑的作用,什么是wins服务器及其作用 -电脑资料
- 双稳态电路的两个稳定状态是什么_555时基电路内部结构及其工作原理
- perf Examples
- 无法解析服务器的dns地址
- android模拟器定制,定制Android模拟器skin
热门文章
- Mac下解决硬盘无法读取问题Mounty for NTFS - 免费让 Mac 原生支持移动硬盘/U盘 NTFS 读写的必备驱动应用
- 计算机考试登记表是准考证嘛
- 导数卷积 牛客 NTT
- 设置浏览器谷歌/edge浏览器允许跨域
- mysql等保测评命令_Mysql等保部分加固
- 缺失值处理(Imputation)
- 计算机网络学生机怎样连接总机,极域课堂管理系统怎么连接老师 学生端连接问题解决方法...
- CSDN博客上传的图片水印去除
- Project-Euler-045思维
- java无响应_Java HttpClient请求无响应解决方案