在函数中,我们需要创建资源(比如: 数据库连接、文件句柄、锁等)
为了在函数执行完毕后,及时释放资源,Go的设计者提供”defer”(延时机制)
?1. 当go执行到一个defer后的语句时,会将defer后的语句先压入到一个栈中,然后继续执行函数下一个语句2. 当函数其他命令执行完毕后,在从defer栈中,依次从栈顶去除语句执行 (注: 遵守栈 先进后出的机制来输出)3. 在defer将语句放入到栈中时,也会将相关的值拷贝同时入栈 案例1 package mainimport “fmt”func sum(n1 int,n2 int) int{//将执行到defer时,会将defer后面的语句,压入到栈内存中(defer栈),暂时不执行//当函数执行完毕后,再从defer栈,按照先进后出的方式,出栈,然后执行defer fmt.Println(“ok1 n1=”,n1)defer fmt.Println(“ok2 n2=”,n2)res := n1 + n2fmt.Println(“ok3 res”,res)return res}func main(){res := 便宜香港vps sum(10,20)fmt.Println(“res=”,res)}
返回
ok3 res 30ok2 n2= 20ok1 n1= 10res= 30#n1、n2被压栈了,所以ok3 res 先出#函数结束后 n1、n2弹栈输出#完事了再输出res=30 案例2 package main import ( “fmt” ) func main() { defer_call() }func defer_call() { defer func() { fmt.Println(“打印前”) }() defer func() { fmt.Println(“打印中”) }() defer func() { fmt.Println(“打印后”) }() panic(“触发异常”) //抛出异常,停止程序}
返回
打印后打印中打印前panic: 触发异常
defer 的执行顺序是后进先出。当出现 panic 语句的时候,会先按照 defer 的后进先出的顺序执行,最后才会执行panic
案例3 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。panic(errors.New(“something wrong”))fmt.Println(“Exit function main.”)}
返回
Enter function main.Enter defer function.panic: something wrongExit defer function.
44157281