<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # defer實現原理 ## 1 defer數據結構 源碼包`src/src/runtime/runtime2.go:_defer`定義了defer的數據結構: ~~~go type _defer struct { sp uintptr //函數棧指針 pc uintptr //程序計數器 fn *funcval //函數地址 link *_defer //指向自身結構的指針,用于鏈接多個defer } ~~~ 我們知道defer后面一定要接一個函數的,所以defer的數據結構跟一般函數類似,也有棧地址、程序計數器、函數地址等等。 與函數不同的一點是它含有一個指針,可用于指向另一個defer,每個goroutine數據結構中實際上也有一個defer指針,該指針指向一個defer的單鏈表,每次聲明一個defer時就將defer插入到單鏈表表頭,每次執行defer時就從單鏈表表頭取出一個defer執行。 下圖展示多個defer被鏈接的過程: ![](https://img.kancloud.cn/e8/df/e8dfc2964738d16d3fbdc088ffa47d9f_681x436.png) 從上圖可以看到,新聲明的defer總是添加到鏈表頭部。 函數返回前執行defer則是從鏈表首部依次取出執行,不再贅述。 一個goroutine可能連續調用多個函數,defer添加過程跟上述流程一致,進入函數時添加defer,離開函數時取出defer,所以即便調用多個函數,也總是能保證defer是按LIFO方式執行的 ## 2 defer的創建和執行 源碼包`src/runtime/panic.go`定義了兩個方法分別用于創建defer和執行defer。 * deferproc(): 在聲明defer處調用,其將defer函數存入goroutine的鏈表中; * deferreturn():在return指令,準確的講是在ret指令前調用,其將defer從goroutine鏈表中取出并執行。 可以簡單這么理解,在編譯階段,聲明defer處插入了函數deferproc(),在函數return前插入了函數deferreturn()
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看