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
举例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的值返回 */
参考资料博客