Go学习——runtime.Caller()函数

简介: Go学习——runtime.Caller()函数

函数:

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

Caller()报告当前go程调用栈所执行的函数的文件和行号信息。

参数解释:

skip:

上溯的栈帧数,0表示Caller的调用者(Caller所在的调用栈)(0-当前函数,1-上一层函数,…)。

pc :

调用栈标识符

file:

文件路径

line:

该调用在文件中的行号

ok:

如果无法获得信息,ok会被设为false

例子:

可能看了上面的解释,对于skip参数依然很迷惑,那我们来看个例子:

此时的项目目录结构:

  blog/
  ├── conf /...
  ├── main.go
  ├── middleware /...
  ├── models /...
  ├── pkg
  │   ├── e /...
  │   ├── logging
  │   │   ├── file.go
  │   │   └── log.go
  │   ├── setting /...
  │   └── util /...
  ├── routers
  │   ├── api
  │   │   ├── auth.go
  │   │   └── v1
  │   │     ├── article.go
  │   │     └── tag.go
  │   └── router.go
  ├── runtime

就拿 blog/routers/api/v1/article.go当例子,在这个文件中GetArticle()中用到了logging.Info():

// followJianYuStudyGo/routers/api/v1/article.go
func GetArticle(c *gin.Context) {
  ...
  } else {
    for _, err := range valid.Errors {
      logging.Info(err.Key, err.Message) // article.go:122  上溯栈帧数skip = 2
    }
  }
  ...
}
// followJianYuStudyGo/pkg/logging/log.go
func Info(v ...interface{}) {
  setPrefix(INFO) // log.go:67 上溯栈帧数skip = 1
  logger.Println(v)
}
func setPrefix(level Level) {
  _, file, line, ok := runtime.Caller(DefaultCallerDepth) // log.go:50 上溯栈帧数skip = 0
    ....
}

如果我们的skip

  • 为0:
    代表上溯的栈帧数为0,返回的file就是调用Caller()的位置:
[INFO][log.go:50]2022/04/29 21:07:11 [created_by 创建人不可以为空]

为1:

代表上溯的栈帧数为1,返回的file就是调用Caller()的上一层位置:

[INFO][log.go:67]2022/04/29 21:25:57 [state 状态只允许为0或1]

为2:

代表上溯的栈帧数为2,返回的file就是调用Caller()的上一层的上一层位置:

[INFO][article.go:122]2022/04/29 20:52:23 [state 状态只允许为0或1]

重点:

 因为我们在logging包里的log.go文件封装了Info()、Debug()、Warn()、....函数,其他地方调用的都是这种封装好的函数,所以如果我们打印日志的时候,想要获取使用了logging.Info()的位置,runtime.Caller(skip int)的skip是要设置为2的(原因见skip=2的部分)!!!!


相关文章
|
3月前
|
程序员 Go 云计算
2023年学习Go语言是否值得?探索Go语言的魅力
2023年学习Go语言是否值得?探索Go语言的魅力
|
3月前
|
缓存 NoSQL Go
通过 SingleFlight 模式学习 Go 并发编程
通过 SingleFlight 模式学习 Go 并发编程
|
7天前
|
JSON 安全 网络协议
go语言使用内置函数和标准库
【10月更文挑战第18天】
11 3
|
9天前
|
设计模式 测试技术 Go
学习Go语言
【10月更文挑战第25天】学习Go语言
16 4
|
2月前
|
Go
go函数
go函数
33 10
|
2月前
|
编译器 Go
go语言学习记录(关于一些奇怪的疑问)有别于其他编程语言
本文探讨了Go语言中的常量概念,特别是特殊常量iota的使用方法及其自动递增特性。同时,文中还提到了在声明常量时,后续常量可沿用前一个值的特点,以及在遍历map时可能遇到的非顺序打印问题。
|
2月前
|
编译器 Go C++
Go to Learn Go之函数
Go to Learn Go之函数
25 0
|
2月前
|
编译器 Go 索引
Go数组、多维数组和切片(动态数组),及常用函数len(),cap(),copy(),append()在切片中的使用
本文介绍了Go语言中数组、多维数组和切片(动态数组)的基本概念和操作,包括数组的定义、初始化、访问,多维数组的定义和访问,以及切片的创建、使用和扩容。同时,还讲解了切片中常用的函数len()、cap()、copy()和append()的使用方法。
|
3月前
|
JSON 中间件 Go
go语言后端开发学习(四) —— 在go项目中使用Zap日志库
本文详细介绍了如何在Go项目中集成并配置Zap日志库。首先通过`go get -u go.uber.org/zap`命令安装Zap,接着展示了`Logger`与`Sugared Logger`两种日志记录器的基本用法。随后深入探讨了Zap的高级配置,包括如何将日志输出至文件、调整时间格式、记录调用者信息以及日志分割等。最后,文章演示了如何在gin框架中集成Zap,通过自定义中间件实现了日志记录和异常恢复功能。通过这些步骤,读者可以掌握Zap在实际项目中的应用与定制方法
125 1
go语言后端开发学习(四) —— 在go项目中使用Zap日志库
|
3月前
|
算法 NoSQL 中间件
go语言后端开发学习(六) ——基于雪花算法生成用户ID
本文介绍了分布式ID生成中的Snowflake(雪花)算法。为解决用户ID安全性与唯一性问题,Snowflake算法生成的ID具备全局唯一性、递增性、高可用性和高性能性等特点。64位ID由符号位(固定为0)、41位时间戳、10位标识位(含数据中心与机器ID)及12位序列号组成。面对ID重复风险,可通过预分配、动态或统一分配标识位解决。Go语言实现示例展示了如何使用第三方包`sonyflake`生成ID,确保不同节点产生的ID始终唯一。
go语言后端开发学习(六) ——基于雪花算法生成用户ID