zoukankan      html  css  js  c++  java
  • 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
    ", 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

  • 相关阅读:
    AtCoder Grand Contest 032-B
    AtCoder Grand Contest 032 A
    高橋君とカード / Tak and Cards AtCoder
    Divisibility by 25 CodeForces
    Fire Again CodeForces
    cctype函数 (字符类型判断)
    蓝桥杯--- 历届试题 国王的烦恼 (并查集)
    蓝桥杯---买不到的数目
    算法课(经典贪心)
    完美的数字
  • 原文地址:https://www.cnblogs.com/neozheng/p/13364079.html
Copyright © 2011-2022 走看看