php转golang中,对defer关键字写一下初步的心得
defer特性:
- defer是自己最先入栈,然后将其位置之后的函数压入栈,等return或者panic以后,按照先进后出的原则自己最后执行,达到目的
- defer的函数的参数在执行defer函数时计算,defer函数的变量的值在执行时计算.执行的时候是多少,就将对应值带入
代码放上来(defer的三个不同位置以及不同的函数返回的值也不同)
package main
import "fmt"
func main() {
println(DeferFunc1(1))
println(DeferFunc2(1))
println(DeferFunc3(1))
}
func DeferFunc1(i int) (t int) {
t = i
fmt.Println("t1",t);
defer func() {
fmt.Println("t3",t);
t += 3
fmt.Println("t4",t);
}()
fmt.Println("t2",t);
return
}
func DeferFunc2(i int) int {
t := i
fmt.Println("t5",t);
defer func() {
fmt.Println("t7",t);
t += 3
fmt.Println("t8",t);
}()
fmt.Println("t6",t);
return t
}
func DeferFunc3(i int) (t int) {
fmt.Println("t9",t);
defer func() {
fmt.Println("t11",t);
t += i
fmt.Println("t12",t);
}()
fmt.Println("t10",t);
return 2
}
先放出来结果
因为结果很长,一次性输出三个函数的值,所以横向摆放,看起来能简单一些
第一个函数
1.该函数初始化时定义了返回参数的名字t 并且定义了返回的类型 t的初始值是0 且t的作用域为整个函数(划重点)
2.该函数执行时 t被赋值为1 所以t1打印出来为1
3.return的时候t的值依旧是1 且return后执行了defer t3位置接受到的t值为1 也是毫无疑问的
4.t3位置后,t+3=4,因为!因为t的作用域是整个函数,所以t=4以后t的值被保留,故第一个函数返回的值是4
第二个函数
1.该函数只定义的返回的值,只要是该类型的变量就可以
2.t初始化为i,由于t是在函数内部定义,所以t的作用域是该函数内
3.return的时候t的值依旧是1
4.t7的时候接收到了t的值为1,t之后+3=4,t8接收也是4,但是在返回的时候由于t的作用域只是该函数内,所以返回的t的值并没有被defer内的操作替换,依旧是1
第三个函数
认真看了前两个的解析的同学应该第三个很好理解了
1.是定义了个作用域整个函数的返回值t
2.返回t的值为2
3.defer接收到返回值t为2 并加了i的值为3
4.由于t的作用域为整个函数,所以返回t的值为3
总结:如果defer要返回某些参数的值,而不是普通的关闭数据库连接等等,那么要选择好对应参数的作用域,作用域不同结果也是大相径庭
(over. 如有不同意见欢迎文明交流,希望各位大佬给出指点意见)