golang:defer 执行顺序

测试代码一:

func TestDefer(t *testing.T) {
    fmt.Println("a")
    defer fmt.Println("b")
    defer c()
    defer d()
    fmt.Println("f")
}

func c() {
    fmt.Println("c")
}

func d() func(){
    fmt.Println("d")
    return func() {
        fmt.Println("e")
    }
}

输出为 a f d c b

结论:defer函数在函数执行结束后执行,若有多个defer函数,则执行顺序为后进先出(从下向上)

 

测试代码二:

func TestDefer(t *testing.T) {
    fmt.Println("a")
    defer fmt.Println("b")
    defer c()
    defer d()()
    fmt.Println("f")
}

func c() {
    fmt.Println("c")
}

func d() func(){
    fmt.Println("d")
    return func() {
        fmt.Println("e")
    }
}

这段代码只是在调用d方法时加了个括号,那么d方法就会立即执行

返回结果为 a d f e c b

我们可以看到 被defer标记的d函数中的程序“立即执行”,而d函数返回的函数则在测试方法结束后 按照“后进先出”的顺序执行。我们可以利用这个特性(函数主体立即执行,返回的函数在主函数结束后执行)做一些功能,如显示函数的执行时间

package main

import (
    "fmt"
    "log"
    "time"
)

func main() {
    bigSlowOperation()
}

func bigSlowOperation() {
    defer trace("bigSlowOperation func")() // do NOT forget the extra parentheses
    fmt.Println("big slow operation after defer trace")
    // ... lots of work
    time.Sleep(10 * time.Second)
}

func trace(msg string) func() {
    start := time.Now()
    log.Printf("enter %s", msg)
    return func() {
        log.Printf("exit %s (%s)", msg, time.Since(start))
    }
}

// 输出结果:
/*
MacBook-Pro:defer_statement zhenxink$ go run defer_order.go
2020/07/23 00:55:27 enter bigSlowOperation func
big slow operation after defer trace
2020/07/23 00:55:37 exit bigSlowOperation func (10.002503591s)
MacBook-Pro:defer_statement zhenxink$
*/

 

参考链接: https://blog.csdn.net/qq_36520153/article/details/82962988?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.edu_weight&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.edu_weight

 

Deferred function run after return statements have updated the function's result variables. Because an anonynous function can access its enclosing function's variables, including named results, a deferred anonymous function can observe the function's results.

A defered anonynous function can even change the values that the enclosing function returns to its caller.

package main

import "fmt"

func main() {
    double(4)
    fmt.Println(triple(4))
}

func double(x int) (result int) {
    defer func() { fmt.Printf("double(%d) = %d\n", x, result) }() // 该匿名函数要加上 ()
    return x + x
}

func triple(x int) (result int) {
    defer func() { result += x }()
    return double(x)
}

// 运行结果:
/*
MacBook-Pro:defer_anonymous_func zhenxink$ go run defer_anonym_func.go
double(4) = 8
double(4) = 8
12
MacBook-Pro:defer_anonymous_func zhenxink$
*/

 

 

fmt.Println 和 log.Println 的区别:

参考链接: https://www.sunzhongwei.com/golang-log-println-fmt-println-diff?from=sidebar_new

 

posted @ 2020-07-23 01:07  neozheng  阅读(894)  评论(0编辑  收藏  举报