package main
import (
"fmt"
)
funcfullName(firstName *string, lastName *string) {
defer fmt.Println("deferred call in fullName")
if firstName == nil {
panic("runtime error: first name cannot be nil")
}
if lastName == nil {
panic("runtime error: last name cannot be nil")
}
fmt.Printf("%s %s\n", *firstName, *lastName)
fmt.Println("returned normally from fullName")
}
funcmain() {
defer fmt.Println("deferred call in main")
firstName := "Elon"
fullName(&firstName, nil)
fmt.Println("returned normally from main")
}
上述代码中,我们只修改了两处,分别在第 8 行和第 20 行添加了延迟函数的调用。
该函数会打印:
1
2
3
4
5
6
7
8
9
10
11
This program prints,
deferred callin fullName
deferred callin main
panic: runtime error: last name cannot be nil
goroutine 1 [running]:
main.fullName(0x1042bf90, 0x0)
/tmp/sandbox060731990/main.go:13+0x280
main.main()
/tmp/sandbox060731990/main.go:22+0xc0
type Error interface {
error// RuntimeError is a no-op function but// serves to distinguish types that are run time// errors from ordinary errors: a type is a// run time error if it has a RuntimeError method.
RuntimeError()
}
而 runtime.Error 接口满足内建接口类型 [error]。
我们来编写一个示例,创建一个运行时 panic。
123456789101112131415
package main
import (
"fmt"
)
funca() {
n := []int{5, 7, 4}
fmt.Println(n[3])
fmt.Println("normally returned from a")
}
funcmain() {
a()
fmt.Println("normally returned from main")
}
panic: runtime error: index out of range
goroutine 1 [running]:
main.a()
/tmp/sandbox780439659/main.go:9 +0x40
main.main()
/tmp/sandbox780439659/main.go:13 +0x20
package main
import (
"fmt"
)
funcr() {
if r := recover(); r != nil {
fmt.Println("Recovered", r)
}
}
funca() {
defer r()
n := []int{5, 7, 4}
fmt.Println(n[3])
fmt.Println("normally returned from a")
}
funcmain() {
a()
fmt.Println("normally returned from main")
}
运行上面程序会输出:
1
2
Recovered runtime error: index outofrange
normally returned from main
package main
import (
"fmt""runtime/debug"
)
funcr() {
if r := recover(); r != nil {
fmt.Println("Recovered", r)
debug.PrintStack()
}
}
funca() {
defer r()
n := []int{5, 7, 4}
fmt.Println(n[3])
fmt.Println("normally returned from a")
}
funcmain() {
a()
fmt.Println("normally returned from main")
}
在上面的程序中,我们在第 11 行使用了 debug.PrintStack() 打印堆栈跟踪。
该程序会输出:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Recovered runtime error: index out of range
goroutine 1 [running]:
runtime/debug.Stack(0x1042beb8, 0x2, 0x2, 0x1c)
/usr/local/go/src/runtime/debug/stack.go:24 +0xc0
runtime/debug.PrintStack()
/usr/local/go/src/runtime/debug/stack.go:16 +0x20
main.r()
/tmp/sandbox949178097/main.go:11 +0xe0
panic(0xf0a80, 0x17cd50)
/usr/local/go/src/runtime/panic.go:491 +0x2c0
main.a()
/tmp/sandbox949178097/main.go:18 +0x80
main.main()
/tmp/sandbox949178097/main.go:23 +0x20
normally returned from main
从输出我们可以看出,首先已经恢复了 panic,打印出 Recovered runtime error: index out of range。此外,我们也打印出了堆栈跟踪。在恢复了 panic 之后,还打印出 normally returned from main。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构