defer的词义:“延迟”,“推迟”
在go语言中,defer关键字来延迟一个函数或者方法的执行
1.defer函数或方法:一个函数或方法的执行被延迟了
2.defer的用法:
A:对象.close(),临时文件的删除。。。
文件.open()
defer close()
读或写
B:go语言中关于异常的处理,使用panic()和recover()
panic函数用于引发恐慌,导致程序中断执行
recover函数用于恢复程序的执行,recover()语法要求必须在defer中执行
3.如果多个defer函数:
栈规则,先延迟后执行,后延迟先执行
4.defer函数传递参数的时候:
defer函数调用时,就已经传递了参数数据了,只是暂时不执行函数中的代码而已
5.defer函数注意点:
当外围函数的语句正常执行完毕时,只有其中所有的延迟函数都执行完毕,外围函数才会真正的结束执行。
当执行外围函数中的return语句时,只有其中所有的延迟函数都执行完毕后,外围函数才会真正返回
当外围函数中的代码引发运行恐慌时,只有其中所有的延迟含税都执行完毕后,该运行时恐慌才会真正被扩展至调用函数
package main
import "fmt"
func main() {
fun1("hello")
fmt.Println("123")
defer fun1("world") //对于被延迟的fun1()来讲,main函数就是外围函数
fmt.Println("456")
fmt.Println("-----------------------------")
a:=2
fmt.Println(a)
defer fun2(a)
a++
fmt.Println("main中打印的a=",a)
fmt.Println("==================================")
fmt.Println(fun3())
}
func fun1(s string) {
fmt.Println(s)
}
func fun2(a int) {
fmt.Println("fun2()函数打印的a=",a)
}
func fun3() int {
fmt.Println("fun3()函数的执行。。。")
defer fun1("hahaha")
return 0
}
输出:
hello
123
456
-----------------------------
2
main中打印的a= 3
==================================
fun3()函数的执行。。。
hahaha
0
fun2()函数打印的a= 2
world
defer与return的注意点:
(1):无参返回值
package main
import (
"fmt"
)
func a() int {
var i int
defer func() {
i++
fmt.Println("defer2:", i)
}()
defer func() {
i++
fmt.Println("defer1:", i)
}()
return i
}
func main() {
fmt.Println("return:", a())
}
输出:
defer1: 1
defer2: 2
return: 0
解释:
返回值由变量i赋值,相当于返回值为i=0。第二个defer中i++ = 1, 第一个defer中i++ = 2,所以最终i的值是2。但是返回值已经被赋值了,就算后续修改i也不会影响返回值。最终返回值返回0,所以main中打印0。
(2)有参返回值
package main
import (
"fmt"
)
func b() (i int) {
defer func() {
i++
fmt.Println("defer2:", i)
}()
defer func() {
i++
fmt.Println("defer1:", i)
}()
return i //或者直接写成return
}
func main() {
fmt.Println("return:", b())
}
输出:
defer1: 1
defer2: 2
return: 2
解释:
这里已经指定了返回值就是i,所以对i进行修改都相当于在修改返回值,所以最终函数的返回值是2。