《Go语言学习笔记》 - 第四章 - 延迟调用

5. 延迟调用

语句defer用来延迟一个方法或者函数的执行。被延迟的方法或者函数直到当前函数执行结束前才会被执行,因此,defer常用于资源释放、解除锁定、错误处理等操作。

5.1 defer的几个注意点
  1. defer的函数只是延迟了调用的时间,但是函数参数的传递是在代码执行到函数所在的那一行时发生的,如果函数传入的参数是一个函数,那么会立即执行。
func main(){
	x,y := 1,2
	defer func(a int){  // 代码执行到这一行时,已经将开辟了变量a的内存,并将x的值拷贝进去,之后x的改变与它无关
		fmt.Println("defer x,y = ",a,y)  
	}(x)

	x += 100
	y += 200
	fmt.Println(x,y)
}
/* 
执行结果为:
		101 202
		defer x,y =  1 202
*/

但函数传入的参数是一个函数时,会先执行该函数。

func a(s string)string{
	fmt.Println("a",s)
	return s
}

func b(s string){
	fmt.Println("b",s)
}

func main(){
	defer b(a("abc"))
	fmt.Println("***")


}

/* 
执行结果为:
		a abc
		***
		b abc
*/
  1. 多个延迟按照FILO的顺序执行。
func a(){
	fmt.Println("被defer的第一个函数!")
}

func b(){
	fmt.Println("被defer的第二个函数!")
}

func c(){
	fmt.Println("被defer的第三个函数!")
}
func main(){
	defer a()
	defer b()
	defer c()
}

/* 
执行结果为:
		被defer的第三个函数!
		被defer的第二个函数!
		被defer的第一个函数!
*/
  1. returnpanic都会终止当前函数流程,引发延迟调用。另外,return会先更新返回值。
func test()(z int){
	defer func(){		
		fmt.Println("defer",z)
		z += 100
	}()

	return 200
}

func main(){
	fmt.Println("test",test())
}

/* 
执行结果:
		defer 200
		test 300
*/

当上述代码执行到test()函数时,首先会为返回值变量z开辟内存空间,然后将匿名函数deferreturn语句先更新返回值,将200放入变量z的内存,在其返回前的一瞬间会执行被defer的匿名函数,故执行结果的第一行为200,随后z自增,然后return

但是,如果返回值没有被命名的话,情况会有所不同,看下面代码:

func test()(int){
	var z int
	defer func(){
		
		fmt.Println("defer",z)
		z += 100
	}()
	z = 200
	return z
}

func main(){
	fmt.Println("test",test())
}

/* 
执行结果:
		defer 200
		test 200
*/

可以看到,上面的代码中并没有给函数的返回值命名,故在一开始执行test()函数时,并不会为返回值开辟内存。在执行函数体代码的过程中,先是定义了z变量,并为其分配内存,然后defer匿名函数,然后给z赋值,将其返回,重点是:在执行return语句更新返回值时,会新开辟一块内存,并将200写入该内存,然后执行被defer的匿名函数,此时,匿名函数中z变量的自增已经不会影响到函数的返回值了,因为z变量与返回值之间没有任何关联。故最后test()函数的返回值也是200

当程序运行遭遇panic时,只有其中所有被defer的函数执行完成之后,该panic才会真正的扩展至调用函数,在panic之后的代码将不会再执行。

func a(){
	fmt.Println("第一个被defer的函数!")
}

func b(){
	fmt.Println("第二个被defer的函数!")
}

func c(){
	fmt.Println("第三个被defer的函数!")

}


func d(){
	fmt.Println("第四个被defer的函数!")
}

func main(){
	defer a()
	defer b()
    panic("pppppanic!")
	defer c()
	defer d()
}

/* 
执行结果:
		第二个被defer的函数!
		第一个被defer的函数!
		panic: pppppanic!
*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值