Go语言之defer

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/woniu317/article/details/82527329

defer关键字

defer和go一样都是Go语言提供的关键字. defer用于资源的释放, 会在函数返回之前进行调用. 要使用好defer最重要的是要理解return执行过程: 先给返回值赋值, 然后调用defer表达式, 最后才是返回到调用函数中. 理解了这句话, 关于defer的疑惑都能迎刃而解了.

例子

例一:

func f1() (result int) {
	defer func() {
		result++
	}()
	return 0
}

return时先将对result赋值0, 然后defer中对result++, 此时result=1; 最后返回时result=1,即调用函数获得值2.

例二:

func f2() (r int) {
	t := 5
	defer func() {
		t = t + 5
	}()
	return t
}

return时先将t的值5赋值给r(值传递); 然后defer中对加5,此时t=10,r=5; 最后返回时r=5, 即调用函数获得值5.

例三:

func f3() (r int) {
	defer func(r int) {
		r = r + 5
	}(r)
	return 1
}

return时先将1赋值给r; 然后调用defer时将r的值传递给defer函数, 注意defer函数中的r已经与函数f3返回的r不是一个变量(值传递), 因此r的修改不会影响f3返回值; 最后返回时r=1, 即调用函数获得值1.

例四:

func addCounter() {
	for count := 0; count < 2; count++ {
		defer lock.Unlock()
		//do someThing
		lock.Lock()
	}
}

将解锁放到defer中是为了防止执行任务(do someThing)时panic导致程序异常结束而未解锁。实际运行时该例子会产生死锁, 原因是(1) Muxtex不是可重入锁; (2) defer会在函数结束时执行,而不是在每一轮for循环结束时执行。正确写法如下:

func addCounter() {
	for count := 0; count < 2; count++ {
		doSomeThing()
	}
}

func doSomeThing() {
	lock.Lock()
    defer lock.Unlock()
    //do someThing
}

猜你喜欢

转载自blog.csdn.net/woniu317/article/details/82527329