golang
defer這個(gè)使用的執(zhí)行流程一直很繞,所以決定寫一篇文記錄一下。
規(guī)則一:當(dāng)defer被聲明時(shí),其參數(shù)就會(huì)被實(shí)時(shí)解析
案例一
package main
import (
"fmt"
)
func main() {
test()
}
func test() {
defer f1(f2())
fmt.Println("2")
return
}
func f1(i int) int {
return i
}
func f2() int {
fmt.Println("1")
return 1
}
輸出:12
案例二
package main
import (
"fmt"
)
func main() {
defer getFunc()()
fmt.Println("2")
}
func getFunc() func() {
fmt.Println("1")
return func() {
fmt.Println("3")
}
}
輸出:123
注意區(qū)分傳入的是函數(shù)變量還是函數(shù)
1、函數(shù)變量
package main
import (
"fmt"
)
func main() {
defer f3(f2)
fmt.Println("2")
}
func f2() int {
fmt.Println("1")
return 1
}
func f3(f func() int) int {
return f()
}
輸出:21
2、函數(shù)
package main
import (
"fmt"
)
func main() {
defer f1(f2())
fmt.Println("2")
}
func f1(i int) int {
return i
}
func f2() int {
fmt.Println("1")
return 1
}
輸出:12
規(guī)則二:defer執(zhí)行順序?yàn)橄冗M(jìn)后出
package main
import (
"fmt"
)
func main() {
defer func() {
fmt.Println("3")
}()
defer func() {
fmt.Println("2")
}()
fmt.Println("1")
}
輸出:123
規(guī)則三:defer可以讀取有名返回值
func main() {
i := 1
defer func() {
i++
fmt.Println(i)
}()
fmt.Println(i)
}
輸出:12
所有規(guī)則復(fù)合體
package main
import (
"fmt"
)
type msg struct {
Num int
}
func (m *msg) print() {
fmt.Println(m.Num)
}
func main() {
m := new(msg)
m.Num = 1
defer m.print()
defer func(m msg) {
m.print()
}(*m)
m.Num = 2
}
輸出:12