defer

defer在函数结束的时候调用一个函数。函数能够经过return返回,或者是panic引发的结束。golang

DerferStmt = "defer" Expressionc#

表达式必须是一个函数或者是方法调用;不能够是括号表达式。内置函数要严格按照要求表达式规范(部份内置函数没法用在表达式)。函数

每次defer语句执行,defer函数中的参数与日常同样的值传递方式,在函数中建立一个新的副本。当函数以return结束时,会当即调用defer的函数,而且以声明defer的逆序方式调用。若是某个defer函数的表达式值为nil,则会出现panic,defer也不执行。google

例如,若是当前函数有一个命名返回值,在defer的匿名函数中能够在函数返回前修改这个返回值spa

若是defer函数有任何的返回值,在函数完成后都会被忽略。.net

最重要的一点:return不是原子指令。code

return语句触发的三部操做blog

  1. 获取须要返回值变量,无论返回值是否声明,对应的都是一个变量;
  2. 栈的形式处理defer函数;
  3. 函数返回

举例get

//example 1
func example1() (result int) {
	defer func() {
		result++
	}()
	return 0
}
//能够理解为
func example1s() (result int) {
	defer func() {
		result++
	}()
	result=0
	return 
}
/**
 * 这里return触发一系列操做
 * 1.给返回变量赋值 result=0
 * 2.处理defer函数,其中defer函数获取到返回变量的地址,而且完成自加操做
 * 3.将返回变量的值返回
 */
//example 2
func example2() (result int) {
	t:=5
	defer func() {
		t=t+5
	}()
	return t
}
//能够理解为
func example2s() (result int) {
	t:=5
	defer func() {
		t=t+5
	}()
	result=t
	return 
}
/**
 * 这里return触发一系列操做
 * 1.给返回变量result赋值 result=t
 * 2.处理defer函数,其中defer函数,让函数中的变量t=t+5
 * 3.将返回变量result的值返回
 */
//example 3
func example3() (result int) {
	defer func(result int) {
		result=result+5
	}(result)
	return 1
}
//能够理解为
func example3s() (result int) {
	defer func(result int) {
		result=result+5
	}(result)
	result=1
	return 
}
/**
 * 这里return触发一系列操做
 * 1.给返回变量result赋值 result=1
 * 2.处理defer函数,其中defer函数,defer函数中的形参result进入到函数内部后变为局部变量,而后在加法运算,但
 *   形参的变化并不会影响外部的同名参数
 * 3.将返回变量result的值返回
 */

参考资料博客

  1. https://golang.google.cn/ref/spec#Defer_statements
  2. https://blog.csdn.net/shenlanzifa/article/details/51540049 (博客上有个转字,没找到原出处,若是知道出处的朋友请告知我,我替换之。)
相关文章
相关标签/搜索