[Golang]恢复panic(recover、defer)-心智图总结

1. 如何让panic,包含一个值
在呼叫panic函数时,把某个值做为参数传给该函数就可以了。panic函数的唯一一个参数是空接口(interface{})类型,也就是可以接受任何类型的值。但是,最好还是传入error类型的错误值。如下面的范例。

package main

import (
	"errors"
	"fmt"
)

func main() {
    fmt.Println("Enter function main.")
    panic(errors.New("something wrong"))
    fmt.Println("Exit function main.") //不会被执行到,因为前一行发生panic
}

https://play.golang.org/p/aQ8eUyyBN1A

2. 正确使用recover函数
Go语言的内建函数recover,专门用於恢复panic。recover函数不用任何参数,并且会返回一个空接口类型的值。

什麽时候呼叫recover?
在panic发生之後? 不行,发生panic後,之後的程序码都不会被执行到。
那放在panic之前呢? 也不行,因为呼叫recover函数时,并没有发生panic,那麽recover函数就不会做任何事情,并且回传nil。

这时候,就要用到defer语句了。defer语句的用途,延迟执行程序代码。
延迟到什麽时候? 延迟到该defer语句的函数即将结束执行的时候。
因此,要恢复panic,需要联合调用defer语句和recover函数。

package main

import (
  "errors"
  "fmt"
)

func main() {
  fmt.Println("Enter function main.")

  defer func() {
    fmt.Println("Enter defer function.")
    if p := recover(); p != nil {
      fmt.Printf("panic: %s\n", p)
    }
    fmt.Println("Exit defer function.")
  }()
  panic(errors.New("something wrong"))

  fmt.Println("Exit function main.")
}

https://play.golang.org/p/bJ20LIjtwDG

3. 函数中有多个defer语句,执行的顺序是?
"defer函数的呼叫与其所属的defer语句的执行顺序完全相反"
也就是说,写在最下面的defer函数会先被执行,其次,是写在它上面的defer函数,而最上面的defer函数,会是最後才被呼叫。
在defer语句每次执行的时候,Go语言会把defer函数,储存到一个Queue中,而这个Queue是FILO

package main

import "fmt"

func main() {
  defer fmt.Println("first defer")
  for i := 0; i < 3; i++ {
    defer fmt.Printf("defer in for [%d]\n", i)
  }
  defer fmt.Println("last defer")
}

https://play.golang.org/p/kvGq_JCfG3v

https://ithelp.ithome.com.tw/upload/images/20201105/20131728VGRQ1pHJuC.png

https://ithelp.ithome.com.tw/upload/images/20201105/20131728gBQ96p6Q8I.png

https://ithelp.ithome.com.tw/upload/images/20201105/20131728zEmVTDlhXq.png

参考来源:
郝林-Go语言核心36讲
https://github.com/hyper0x/Golang_Puzzlers


<<:  分享 : SpyGlass CDC 流程深入理解

>>:  番外篇 - NestJs - Guard

Day 08 Azure cognitive service: object detection- 匡出照片中的喵

Azure cognitive service: Object Detection- 匡出照片中的喵...

Day 17 ( 中级 ) 立体空间 ( 三度空间 )

立体空间 ( 三度空间 ) 教学原文参考:立体空间 ( 三度空间 ) 这篇文章会介绍,如何在 Scr...

Day5# For loop

默默的来到了第五天,今天要认识 Go 的回圈应用,总算开始要有写程序的感觉了! 如果已经准备好了,那...

009-实作经验

继上篇提到的内容,从我体悟到这些心得,到我实际使用并且得到回馈的时期,是换了一份新的工作的时候。 由...

Day 14 - 设定 VLAN

继昨天快速地介绍完 VLAN 後,我们来设定一下 目前是要在 PVE 与路由器进行设定。 我的路由器...