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的部分)!!!!


相关文章
|
6天前
|
自然语言处理 Go 索引
Go语言学习8-接口类型
【4月更文挑战第1天】本篇 Huazie 向大家介绍 Go 语言中的接口类型
22 2
Go语言学习8-接口类型
|
6天前
|
SQL 前端开发 Go
编程笔记 GOLANG基础 001 为什么要学习Go语言
编程笔记 GOLANG基础 001 为什么要学习Go语言
|
6天前
|
Go 数据处理
Go杂记1-切片Slice作为函数参数那点事儿
Go杂记1-切片Slice作为函数参数那点事儿
8 0
|
6天前
|
存储 编译器 Go
Go语言学习12-数据的使用
【5月更文挑战第5天】本篇 Huazie 向大家介绍 Go 语言数据的使用,包含赋值语句、常量与变量、可比性与有序性
50 6
Go语言学习12-数据的使用
|
6天前
|
Java Go
Go语言学习11-数据初始化
【5月更文挑战第3天】本篇带大家通过内建函数 new 和 make 了解Go语言的数据初始化过程
30 1
Go语言学习11-数据初始化
|
6天前
|
JavaScript 前端开发 Go
Go语言的入门学习
【4月更文挑战第7天】Go语言,通常称为Golang,是由Google设计并开发的一种编程语言,它于2009年公开发布。Go的设计团队主要包括Robert Griesemer、Rob Pike和Ken Thompson,这三位都是计算机科学和软件工程领域的杰出人物。
17 1
|
6天前
|
Go
|
6天前
|
存储 Go 开发者
【Go语言专栏】函数在Go语言中的使用与实现
【4月更文挑战第30天】本文介绍了Go语言中函数的使用和实现,包括函数定义、参数传递、返回值、匿名函数、变长参数、函数类型、闭包和错误处理。通过示例展示了如何定义和调用函数,以及如何利用闭包和递归解决问题。此外,还提到了Go函数作为一等公民的特性,允许存储和传递。进一步学习可参考官方文档和相关书籍。
|
6天前
|
Go
Golang深入浅出之-Go语言函数基础:定义、调用与多返回值
【4月更文挑战第21天】Go语言函数是代码组织的基本单元,用于封装可重用逻辑。本文介绍了函数定义(包括基本形式、命名、参数列表和多返回值)、调用以及匿名函数与闭包。在函数定义时,注意参数命名和注释,避免参数顺序混淆。在调用时,要检查并处理多返回值中的错误。理解闭包原理,小心处理外部变量引用,以提升代码质量和可维护性。通过实践和示例,能更好地掌握Go语言函数。
31 1
Golang深入浅出之-Go语言函数基础:定义、调用与多返回值
|
6天前
|
程序员 Go API
【Go语言快速上手(二)】 分支与循环&函数讲解
【Go语言快速上手(二)】 分支与循环&函数讲解