zoukankan      html  css  js  c++  java
  • defer综合

    A "defer" statement invokes a function whose execution is deferred to the moment the surrounding function returns, either because the surrounding function executed a return statement, reached the end of its function body, or because the corresponding goroutine is panicking.

    defer语句会在以下几种情况下被执行:
    a. 函数执行return语句
    b. 执行到函数体结尾
    c. goroutine panic之前
     

    Each time a "defer" statement executes, the function value and parameters to the call are evaluated as usual and saved anew but the actual function is not invoked. Instead, deferred functions are invoked immediately before the surrounding function returns, in the reverse order they were deferred. That is, if the surrounding function returns through an explicit return statement, deferred functions are executed after any result parameters are set by that return statement but before the function returns to its caller. If a deferred function value evaluates to nil, execution panics when the function is invoked, not when the "defer" statement is executed. 

    每次执行defer语句时,会将其定义的函数和参数保存在一个栈中,但是定义的函数并不会被执行。但是,在外层函数退出之前,defer函数会按照定义的顺序逆序执行。如果外层函数通过显示return语句返回,则defer定义的函数是在设置结果参数之后,返回调用方之前执行。如果defer要执行的函数为nil,则会在定义的函数调用时产生panic,而不是defer语句执行时。

     

    1. defer原理分析

    a. 多个defer执行顺序

    当一个函数中存在多个defer语句时,函数返回之前会按照defer定义的顺序逆序执行,也就是说最先注册的defer函数最后执行。

    b. defer语句执行时拷贝时机

    当defer语句执行时,会将当前时刻的函数值和函数参数进行注册。注册完成之后再次修改函数值和函数参数将不会生效。

    c. return & defer

    return x :返回值 = x   +   RET指令

    defer 原理 :返回值 = x + defer语句 + RET指令

    d. defer & 闭包

    func main() {
      x := 1
      defer func() {
        fmt.Println(x)      // 2
      }()
      x++
    }

    上例中的 func()是一个闭包,闭包的变量本质是对上层变量的引用。

    type Closure struct {

      F func()

      x *int

    }

    相比于直接调用函数,延迟调用需要花费更大的代价。这其中包括注册、调用等操作,还有额外的缓存开销。

    对于性能要求高且压力大的算法,应该尽量避免延迟调用。

  • 相关阅读:
    Python疑难杂症:SyntaxError: NonASCII character Python中文处理问题
    程序员健康大全透视身体24小时工作时间表
    ConnectionTimeout,CommandTimeout和executionTimeout的理解
    google map api 与jquery结合使用(3) 图标样式,使用xml和异步请求【转帖】
    新手8周跑步训练计划
    57商城温州地区最大本土网上超市
    7 款仿照 Sinatra 思路的 .NET 框架
    线程池的原理和连接池的原理
    免费网站模版:一个黑色系的公司网站模版(flash幻灯)
    深入浅出REST
  • 原文地址:https://www.cnblogs.com/juanmaofeifei/p/13296645.html
Copyright © 2011-2022 走看看