1. 如何让panic,包含一个值
在呼叫panic函数时,把某个值做为参数传给该函数就可以了。panic函数的唯一一个参数是空接口(interface{})类型,也就是可以接受任何类型的值。但是,最好还是传入error类型的错误值。如下面的範例。
package mainimport ("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 mainimport ( "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 mainimport "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
参考来源:
郝林-Go语言核心36讲
https://github.com/hyper0x/Golang_Puzzlers