golang: 掌握defer

一,执行顺序:

先进后出,类似于栈的特性

1,代码:

func deferAndPanic() {
    defer func() { fmt.Println("defer1") }()
    defer func() { fmt.Println("defer2") }()
    defer func() { fmt.Println("defer3") }()
    panic("异常内容")
}


// 入口函数
func main() {
    deferAndPanic()
    fmt.Println("函数执行结束")
}

2,运行结果:

$ go run main.go 
defer3
defer2
defer1
panic: 异常内容

goroutine 1 [running]:
main.deferAndPanic()
        /data/goapp/imagebank/main.go:14 +0x65
main.main()
        /data/goapp/imagebank/main.go:21 +0x13
exit status 2

二,defer语句出现时,参数的值就已经确定

代码:

func dd() {
    var a=1
    defer fmt.Println(a)
    a=2
    return
}

// 入口函数
func main() {
    dd()
}

运行结果:

$ go run main.go 
1

三,有defer语句的函数return的执行过程:

代码:

func dd() (res int){
    i:=1
    defer func() {
       res++
    }()
    return i
}

// 入口函数
func main() {
    fmt.Println("结果:",dd())
}

说明:

函数的 return 语句并不是原子的,实际执行分为设置返回值和 ret两步,
defer 语句实际执行在返回前,即拥有 defer的函数返回过程是:设置返回值→执行 defer→ret。,

 所以 return 语句先把res设置为i的值,即1,defer语句又把res递增1,所以最终返回2

运行结果:

$ go run main.go 
结果: 2

四,defer函数中的变量

延迟函数中的变量i在编译时绑定了原函数dd中的变量i,

所以延迟函数最终获取的是i的最终值

代码:

func dd() {
    var i=0
    defer func() {
       fmt.Println(i)
    }()
    i++
}

// 入口函数
func main() {
    dd()
}

运行结果:

$ go run main.go 
1

 

posted @ 2025-03-15 15:15  刘宏缔的架构森林  阅读(23)  评论(0)    收藏  举报