Golang

关注公众号 jb51net

关闭
首页 > 脚本专栏 > Golang > golang defer执行顺序

golang defer执行顺序全面详解

作者:werbenhu

这篇文章主要为大家介绍了golang defer执行顺序全面详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

defer的执行顺序

多个defer是一个的结构,是先进后出,下面这个代码的输出顺序是CBA。

package main
import "fmt"
func main() {
    defer func1()
    defer func2()
    defer func3()
}
func func1() {
    fmt.Println("A")
}
func func2() {
    fmt.Println("B")
}
func func3() {
    fmt.Println("C")
}

defer和return的顺序

先执行return,再执行defer。

package main
import "fmt"
func deferFunc() {
    fmt.Println("defer func called")
}
func returnFunc() int {
    fmt.Println("return func called")
    return 0
}
func returnAndDefer() int {
    defer deferFunc()
    return returnFunc()
}
func main() {
    returnAndDefer()
}
// output:
// return func called 
// defer func called

函数命名返回值遇见defer

package main
import "fmt"
func foo() (t int) {
    defer func() {
        t = t * 10
    }()
    return 1
}
func main() {
    fmt.Println(foo())
}
// output: 10

defer和panic

panic阻断defer

import (
    "fmt"
)
func deferFn() {
    defer func() { fmt.Println("defer before panic 1") }()
    defer func() { fmt.Println("defer before panic 2") }()
    panic("exit")
    defer func() { fmt.Println("defer after panic") }()
}
func main() {
    deferFn()
    fmt.Println("main exit")
}
/*
output:
defer before panic 2
defer before panic 1
panic: exit
...
*/

defer里面的recover

defer在panic 后依然有效

package main
import (
    "fmt"
)
func deferFn() {
    defer func() {
        fmt.Println("defer before panic 1")
        if err := recover(); err != nil {
            fmt.Println(err)
        }
    }()
    defer func() { fmt.Println("defer before panic 2") }()
    panic("panic info")
    defer func() { fmt.Println("defer after panic") }()
}
func main() {
    deferFn()
    fmt.Println("main exit")
}
/*
output:
defer before panic 2
defer before panic 1
panic info
main exit
*/

defer中包含panic

panic仅有最后一个可以被revover捕获

package main
import (
    "fmt"
)
func main() {
    defer func() {
        if err := recover(); err != nil {
            fmt.Println(err)
        } else {
            fmt.Println("defer call")
        }
    }()
    defer func() {
        panic("defer panic")
    }()
    panic("main panic")
}
// output: defer panic

defer中函数有参数和包含子函数

package main
import "fmt"
func foo(index int, value int) int {
    fmt.Println(index)
    return index
}
func main() {
    defer foo(1, foo(3, 0))
    defer foo(2, foo(4, 0))
}
// output: 3 4 2 1

测试练习

package main
import "fmt"
func DeferFunc1(i int) (t int) {
    t = i
    defer func() {
        t += 3
    }()
    return t
}
func DeferFunc2(i int) int {
    t := i
    defer func() {
        t += 3
    }()
    return t
}
func DeferFunc3(i int) (t int) {
    defer func() {
        t += i
    }()
    return 2
}
func DeferFunc4() (t int) {
    defer func(i int) {
        fmt.Println(i)
        fmt.Println(t)
    }(t)
    t = 1
    return 2
}
func main() {
    fmt.Println(DeferFunc1(1))
    fmt.Println(DeferFunc2(1))
    fmt.Println(DeferFunc3(1))
    DeferFunc4()
}

以上就是golang defer执行顺序全面详解的详细内容,更多关于golang defer执行顺序的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文