golang 打印函数名/文件名/行号 Callers

 golang 的runtime库,提供Caller函数,可以返回运行时正在执行的文件名和行号:
函数定义:
func Caller(skip int) (pc uintptr, file string, line int, ok bool) {}
函数用法:
_, file, line, ok := runtime.Caller(0)

package main
import ("fmt";"runtime")

 
func main() {
  funcName,file,line,ok := runtime.Caller(0)
  if(ok){
	fmt.Println("func name: " + runtime.FuncForPC(funcName).Name())
	fmt.Printf("file: %s, line: %d\n",file,line)
   }
}

 

==================================

runtime.Caller 学习笔记

今天阅读log的源码的时候发现他会去调用runtime.Caller 获取文件名称跟行数好奇心就来了,java或者其他语言的开发中log打印文件名称跟行数是一种很正常的事,具体怎么实现的一直没有研究过。今天就研究下golang中是怎么实现的

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

这是函数详情,更深入的详情你可以自己查询go的源码

func main() {
    call()
}

func call() {
    var calldepth = 1;
    fmt.Println(runtime.Caller(calldepth))
}

写了一个很简单的测试函数开始学习。一开始不是太懂他的参数的skip是什么意思,多看了下log的源码发现这个的意思是层级的意思。经过多次测试发现层级从0开始到3的时候结束。

17356603 /Users/mac-mini/go/src/demo/3/demo2.go 14 true
17356511 /Users/mac-mini/go/src/demo/3/demo2.go 9 true
16939329 /usr/local/go/src/runtime/proc.go 198 true
17095168 /usr/local/go/src/runtime/asm_amd64.s 2361 true

结果一目了然,层次为0的时候返回我们调用runtime.Caller的地方.为1的时候就是我们调用call函数的地方。 2跟3已经是go源码的调用了应该是用不到。

本来写完了都已经发布了,后来阅读了下runtime.Caller的源码发现这货底层是能获取到调用函数名称的,可是他不返回。

_, frame, _ := stackExpander.next(callers, true)
pc = frame.PC
file = frame.File
line = frame.Line

这个是Caller源码的最后几行,他这里获取了一个frame从中取到了pc,file,line。当我翻阅Frame的struct后发现有个string类型名称为Function属性,打开下断点发现值是真的有正确。emmm具体的不知道google是怎么设计的,不过应该是的有他们的道理吧。
 

 

 

 

Golang 中,Future 和 Promise 的概念通常被称为 Channel。Channel 是一种用于在 Goroutine 之间进行通信和同步的机制,类似于 Unix 系统中的管道。Future 和 Promise 的概念可以通过 Channel 来实现。 Future 是一个表示异步操作结果的对象,它可以让你在不阻塞当前线程的情况下等待异步操作完成。在 Golang 中,可以使用一个带缓冲的 Channel 来实现 Future。当异步操作完成时,会向 Channel 中写入结果,而 Future 对象会等待 Channel 中有数据可读。 例如,下面的代码演示了如何使用 Channel 实现 Future: ``` func asyncOperation() <-chan int { result := make(chan int, 1) go func() { // 异步操作 time.Sleep(time.Second) result <- 42 }() return result } func main() { // 启动异步操作 future := asyncOperation() // 在不阻塞当前线程的情况下等待异步操作完成 fmt.Println("Waiting for async operation...") value := <-future fmt.Printf("Async operation completed with result: %d\n", value) } ``` Promise 是一个表示异步操作的未来结果的对象,它可以让你在异步操作完成之前先返回一个对象,然后在异步操作完成之后再向该对象写入结果。在 Golang 中,可以使用一个未缓冲的 Channel 来实现 Promise。当异步操作完成时,会向 Channel 中写入结果,而 Promise 对象在等待 Channel 可写时会被阻塞。 例如,下面的代码演示了如何使用 Channel 实现 Promise: ``` type Promise struct { result chan int } func asyncOperation() *Promise { promise := &Promise{make(chan int)} go func() { // 异步操作 time.Sleep(time.Second) promise.result <- 42 }() return promise } func main() { // 启动异步操作 promise := asyncOperation() // 在异步操作完成之前先返回一个对象 fmt.Println("Async operation started...") // 在异步操作完成之后再获取结果 value := <-promise.result fmt.Printf("Async operation completed with result: %d\n", value) } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值