Go 编程 | 连载 26 - Go 的 panic 与 recover(上)

简介: Go 编程 | 连载 26 - Go 的 panic 与 recover

一、panic 和 recover

Go 语言中的错误处理机制是如果一个可能造成错误的函数,需要在该函数的返回值中增加一个错误接口。如果函数调用成功,错误接口将被返回 nil,如果调用失败,则返回具体的错误内容。

在函数调用后需要检查错误,进行必要的错误处理。

Go 编程 | 连载 19 - 接口的应用 讲到了实例化错误类型的多种方式,这里不再赘述。

panic

panic 在 Go 语言中表示是宕机,既服务停止或者程序终止运行。

Go 语言中可以手动触发 panic,让程序终止运行,这样可以在程序发生错误时及时止损。panic 发生时会将堆栈和 goroutine 信息输出到控制台,可以据此知晓发生错误的位置,如果在编译时加入的调试信息甚至连 panic 发生时的变量运行状态都可以获得。

func main() {
   var info any
   info = "crash"
   panic(info)
   fmt.Println("Hello Go")
}
复制代码

执行上述代码,输出结果如下:

panic: crash
goroutine 1 [running]:
main.main()
  /ex25.go:6 +0x27
复制代码

只通过一个 panic 函数就是程序终止运行,panic 函数后面的代码也没有执行。panic 函数是 Go 的内置函数,该函数的参数是一个 any 类型,而 any 是一个接口。

当 panic 发生时,panic 函数后的代码将不会被执行,但是 panic 函数前面已经运行过的 defer 语句仍然会在 panic 发生时运行。

func main() {
   defer fmt.Println("panic 前")
   var info any
   info = "crash"
   panic(info)
   fmt.Println("Hello Go")
   defer fmt.Println("panic 后")
}
复制代码

执行上述代码,输出结果如下:

panic 前
panic: crash
goroutine 1 [running]:
main.main()
  /ex25.go:10 +0x73
复制代码

panic 发生前,在 panic 函数前面的 defer 会优先执行,但是在 panic 函数后的 defer 不会被执行,因为 panic 发生程序停止服务,包括 defer 语句所有的代码都不会被执行。

recover

代码运行时的发生的错误可以通过 deferrecover 实现错误捕捉和恢复。让代码发生在泵阔后允许继续运行,类似其他语言中的 try-catch

Go 中没有异常的概念,只有错误,panic 函数触发宕机就类似于其他语言中的异常。

recover 函数的返回值为任意内容

func recover() any
复制代码
package main
//noinspection ALL
import (
   "fmt"
   "runtime"
)
type panicContent struct {
   function string
}
//noinspection ALL
func main() {
   fmt.Println("手动触发 painc 前")
   samFun(func() {
      panic(&panicContent{
         "手动触发 panic",
      })
   })
   fmt.Println("手动触发 painc 后")
   fmt.Println("空指针导致 panic")
   samFun(func() {
      fmt.Println("赋值前")
      var a *int
      *a = 1
      fmt.Println("赋值后")
   })
   fmt.Println("panic 后")
}
func samFun(f func()) {
   defer func() {
      // 发生 panic 时,获取 panic 函数传递的上下文并打印
      err := any(recover())
      switch err.(type) {
      case runtime.Error:
         fmt.Println("runtime error:", err)
      default:
         fmt.Println("error:",err)
      }
   }()
   f()
}
复制代码

执行上述代码,输出结果如下:

手动触发 painc 前
error: &{手动触发 panic}
手动触发 painc 后
空指针导致 panic
赋值前
runtime error: runtime error: invalid memory address or nil pointer dereference
panic 发生后
复制代码

panic 函数和 recover 函数同时存在,程序不会宕机,执行对应的 defer 语句后,从宕机点退出当前函数后继续执行。

二、panic 和 recover 的坑

image.png

Go 中错误与异常的区分

image.png

image.png

image.png

image.png

go 中的 ”try catch“ 这默写

image.png

这默写是不行的

image.png

panic 中的坑


相关文章
|
12天前
|
数据采集 监控 Java
go语言编程学习
【11月更文挑战第3天】
30 7
|
17天前
|
Unix Linux Go
go进阶编程:Golang中的文件与文件夹操作指南
本文详细介绍了Golang中文件与文件夹的基本操作,包括读取、写入、创建、删除和遍历等。通过示例代码展示了如何使用`os`和`io/ioutil`包进行文件操作,并强调了错误处理、权限控制和路径问题的重要性。适合初学者和有经验的开发者参考。
|
25天前
|
Java 大数据 Go
Go语言:高效并发的编程新星
【10月更文挑战第21】Go语言:高效并发的编程新星
47 7
|
1月前
|
Go 数据处理 调度
Go语言中的并发模型:解锁高效并行编程的秘诀
本文将探讨Go语言中独特的并发模型及其在现代软件开发中的应用。通过深入分析 Goroutines 和 Channels,我们将揭示这一模型如何简化并行编程,提升应用性能,并改变开发者处理并发任务的方式。不同于传统多线程编程,Go的并发方法以其简洁性和高效性脱颖而出,为开发者提供了一种全新的编程范式。
|
1月前
|
并行计算 算法 搜索推荐
探索Go语言的高并发编程与性能优化
【10月更文挑战第10天】探索Go语言的高并发编程与性能优化
|
2月前
|
存储 缓存 Go
go语言编程系列(五)
go语言编程系列(五)
|
2月前
|
搜索推荐 Java 编译器
go语言编程系列(四)
go语言编程系列(四)
|
2月前
|
存储 JSON 安全
go语言编程系列(七)
go语言编程系列(七)
|
2月前
|
存储 安全 编译器
go语言编程系列(六)
go语言编程系列(六)
|
2月前
|
自然语言处理 Java 测试技术
go语言编程系列(二)
go语言编程系列(二)