本期分享:
1. runtime.Caller(1)
获取调用者信息
2. for循环
+ select{}
语法
正文:
runtime.Caller(1)
获取调用者信息在 Go 语言中,runtime.Caller(1)
是 runtime
包提供的一个函数,用于获取当前 goroutine 的调用堆栈中的特定调用者的信息。这里的 1
表示要跳过的调用帧数。具体来说,当你调用 runtime.Caller(1)
时,它会返回调用 runtime.Caller
的函数的调用者的信息。
这个函数的返回值:
以下是一个简单的示例,展示了如何在 Go 程序中使用 runtime.Caller(1)
来获取并打印调用者的信息:
func getCallerInfo() (string, string, int) {
pc, file, line, ok := runtime.Caller(1)
if !ok {
return "", "", 0
}
funcName := runtime.FuncForPC(pc).Name()
return funcName, file, line
}
func TestCallerInfo(t *testing.T) {
funcName, file, line := getCallerInfo()
fmt.Printf("func name: %s \n", funcName)
fmt.Printf("call file: %s \n", file)
fmt.Printf("code line: %d \n", line)
}
输出:
func name: code/code_28.TestCallerInfo
call file: E:/xxx/code/code_28/caller_info_test.go
code line: 19
1)获取调用堆栈信息有一定的性能开销,因此不建议在性能敏感的代码路径中频繁使用。
2)在生产环境中,调用堆栈信息通常用于日志记录,以便在出现问题时进行分析和调试。
3)runtime.Caller
和相关的函数是 Go 语言提供的底层运行时接口,它们允许开发者深入了解程序的执行过程,但也需要谨慎使用以避免引入不必要的复杂性或性能问题。
for循环
+ select{}
语法在Go语言中,for循环
+ select{}
语法是一种用于处理多个通道(channel)的并发操作的语法结构。它允许你在一个循环中同时等待多个通道的操作,并且可以根据哪个通道准备好进行相应的处理。
for循环
+ select{}
语法通常用于以下场景:
1)并发处理多个通道:当你需要同时处理多个通道的输入或输出时,可以使用 for select 来避免阻塞并高效地处理数据。
2)超时处理:通过在 select 语句中添加 time.After 或 time.Tick 通道,可以实现超时机制或定时任务。
3)资源管理:在处理多个资源时,可以使用 for select 来确保资源的正确释放和清理。
4)事件驱动编程:在事件驱动的程序中,for select 可以用于监听多个事件源,并根据事件的发生进行相应的处理。
以下是一个简单的示例,展示了如何使用 for select 来处理多个通道
func TestForSelect(t *testing.T) {
ch1 := make(chan int)
ch2 := make(chan string)
go func() {
for i := 0; i < 5; i++ {
ch1 <- i
time.Sleep(time.Second)
}
close(ch1)
}()
go func() {
for i := 0; i < 5; i++ {
ch2 <- fmt.Sprintf("message %d", i)
time.Sleep(2 * time.Second)
}
close(ch2)
}()
for {
select {
case num, ok := <-ch1:
if !ok {
ch1 = nil // 通道关闭后设置为 nil,避免重复关闭
} else {
fmt.Println("Received from ch1:", num)
}
case msg, ok := <-ch2:
if !ok {
ch2 = nil // 通道关闭后设置为 nil,避免重复关闭
} else {
fmt.Println("Received from ch2:", msg)
}
case <-time.After(3 * time.Second):
fmt.Println("Timeout")
default:
fmt.Println("No data received")
time.Sleep(time.Second)
}
// 当所有通道都关闭时退出循环
if ch1 == nil && ch2 == nil {
break
}
}
}
在这个示例中,我们创建了两个通道 ch1 和 ch2,并分别在两个 goroutine 中向它们发送数据。在主 goroutine 中,我们使用 for select 来同时监听这两个通道,并根据哪个通道准备好进行相应的处理。当所有通道都关闭时,循环退出。
1)通道关闭:在处理通道时,需要注意通道的关闭状态,避免在通道关闭后继续读取或写入数据。
2)默认操作:default 分支在没有通道准备好时会被执行,可以用于避免阻塞。
3)超时处理:通过 time.After 或 time.Tick 通道可以实现超时机制,但需要注意避免资源泄漏。
通过合理使用 for select,你可以编写出高效、并发的Go程序。
本节完~
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。