<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智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                ## 節點樹 Go 節點是包含大量屬性的結構。你將在第 4 章“復合類型的使用”中學習有關定義和使用 Go struct的更多信息。Go 編譯器的模塊根據 Go 編程語言的語法對 Go 程序中的所有內容進行解析和分析。此分析的最終結果是一棵樹,該樹對應于所提供的 Go 代碼,并以適合編譯器方式表示程序結構。 > Tip: 需要注意的是,`go tool 6g -W test.go`在更新的 Go 版本中無法正常運行。取而代之你應該使用`go tool compile -W test.go`。 本節將首先使用以下 Go 代碼(保存為`nodeTree.go`)作為示例,以查看 go 工具可以為我們提供的底層信息: ```Go package main import ( "fmt" ) func main() { fmt.Println("Hello there!") } ``` nodeTree.go 的 Go 代碼非常容易理解,因此你不會對它感到驚訝其輸出,接下來是: ```shell $ go run nodeTree.go Hello there! ``` 通過執行下一個命令來查看一些 Go 的內部工作方式: ```shell $ go tool compile -W nodeTree.go before walk main . CALLFUNC l(8) tc(1) STRUCT-(int, error) . . NAME-fmt.Println a(true) l(263) x(0) class(PFUNC) tc(1) used FUNC- func(...interface {}) (int, error) . . DDDARG l(8) esc(no) PTR64-*[1]interface {} . CALLFUNC-list . . CONVIFACE l(8) esc(h) tc(1) implicit(true) INTER-interface {} . . . NAME-main.statictmp_0 a(true) l(8) x(0) class(PEXTERN) tc(1) used string . VARKILL l(8) tc(1) . . NAME-main..autotmp_0 a(true) l(8) x(0) class(PAUTO) esc(N) used ARRAY-[1]interface {} after walk main . CALLFUNC-init . . AS l(8) tc(1) . . . NAME-main..autotmp_0 a(true) l(8) x(0) class(PAUTO) esc(N) tc(1) addrtaken assigned used ARRAY-[1]interface {} .. AS l(8) tc(1) .. . NAME-main..autotmp_2 a(true) l(8) x(0) class(PAUTO) esc(N) tc(1) assigned used PTR64-*[1]interface {} .. . ADDR l(8) tc(1) PTR64-*[1]interface {} .. . . NAME-main..autotmp_0 a(true) l(8) x(0) class(PAUTO) esc(N) tc(1) addrtaken assigned used ARRAY-[1]interface {} . . BLOCK l(8) . . BLOCK-list . . . AS l(8) tc(1) hascall . . . . INDEX l(8) tc(1) assigned bounded hascall INTER-interface {} . . . . . IND l(8) tc(1) implicit(true) assigned hascall ARRAY- [1]interface {} . . . . . . NAME-main..autotmp_2 a(true) l(8) x(0) class(PAUTO) esc(N) tc(1) assigned used PTR64-*[1]interface {} . . . . . LITERAL-0 l(8) tc(1) int . . . . . . uint8 .. . . . ADDR l(8) tc(1) PTR64-*string .. . . . . NAME-main.statictmp_0 a(true) l(8) x(0) class(PEXTERN) tc(1) addrtaken used string . . . . . ADDR a(true) l(8) tc(1) PTR64-*uint8 . . . . NAME-type.string a(true) x(0) class(PEXTERN) tc(1) EFACE l(8) tc(1) INTER-interface {} . . BLOCK l(8) . . BLOCK-list . . . AS l(8) tc(1) hascall . . . . NAME-main..autotmp_1 a(true) l(8) x(0) class(PAUTO) esc(N) tc(1) assigned used SLICE-[]interface {} .. . . SLICEARR l(8) tc(1) hascall SLICE-[]interface {} .. . . . NAME-main..autotmp_2 a(true) l(8) x(0) class(PAUTO) esc(N) tc(1) assigned used PTR64-*[1]interface {} . CALLFUNC l(8) tc(1) hascall STRUCT-(int, error) . . NAME-fmt.Println a(true) l(263) x(0) class(PFUNC) tc(1) used FUNC- func(...interface {}) (int, error) . . DDDARG l(8) esc(no) PTR64-*[1]interface {} . CALLFUNC-list . . AS l(8) tc(1) . . . INDREGSP-SP a(true) l(8) x(0) tc(1) addrtaken main.__ SLICE- []interface {} . . . NAME-main..autotmp_1 a(true) l(8) x(0) class(PAUTO) esc(N) tc(1) assigned used SLICE-[]interface {} . VARKILL l(8) tc(1) . . NAME-main..autotmp_0 a(true) l(8) x(0) class(PAUTO) esc(N) tc(1) addrtaken assigned used ARRAY-[1]interface {} before walk init . IF l(1) tc(1) . . GT l(1) tc(1) bool . . . NAME-main.initdone a(true) l(1) x(0) class(PEXTERN) tc(1) assigned used uint8 . . . LITERAL-1 l(1) tc(1) uint8 . IF-body . . RETURN l(1) tc(1) . IF l(1) tc(1) . . EQ l(1) tc(1) bool . . . NAME-main.initdone a(true) l(1) x(0) class(PEXTERN) tc(1) assigned used uint8 . . . LITERAL-1 l(1) tc(1) uint8 . IF-body . . CALLFUNC l(1) tc(1) . . . NAME-runtime.throwinit a(true) x(0) class(PFUNC) tc(1) used FUNC-func() . AS l(1) tc(1) . . NAME-main.initdone a(true) l(1) x(0) class(PEXTERN) tc(1) assigned used uint8 . . LITERAL-1 l(1) tc(1) uint8 . CALLFUNC l(1) tc(1) . . NAME-fmt.init a(true) l(1) x(0) class(PFUNC) tc(1) used FUNC-func() . AS l(1) tc(1) . . NAME-main.initdone a(true) l(1) x(0) class(PEXTERN) tc(1) assigned used uint8 . . LITERAL-2 l(1) tc(1) uint8 . RETURN l(1) tc(1) after walk init . IF l(1) tc(1) . . GT l(1) tc(1) bool . . . NAME-main.initdone a(true) l(1) x(0) class(PEXTERN) tc(1) assigned used uint8 . . . LITERAL-1 l(1) tc(1) uint8 . IF-body . . RETURN l(1) tc(1) . IF l(1) tc(1) . . EQ l(1) tc(1) bool . . . NAME-main.initdone a(true) l(1) x(0) class(PEXTERN) tc(1) assigned used uint8 . . . LITERAL-1 l(1) tc(1) uint8 . IF-body . . CALLFUNC l(1) tc(1) hascall . . . NAME-runtime.throwinit a(true) x(0) class(PFUNC) tc(1) used FUNC-func() . AS l(1) tc(1) . . NAME-main.initdone a(true) l(1) x(0) class(PEXTERN) tc(1) assigned used uint8 . . LITERAL-1 l(1) tc(1) uint8 . CALLFUNC l(1) tc(1) hascall . . NAME-fmt.init a(true) l(1) x(0) class(PFUNC) tc(1) used FUNC-func() . AS l(1) tc(1) . . NAME-main.initdone a(true) l(1) x(0) class(PEXTERN) tc(1) assigned used uint8 . . LITERAL-2 l(1) tc(1) uint8 . RETURN l(1) tc(1) ``` Go 編譯器及其工具在后臺做很多事情,即使對于像`nodeTree.go`這樣的簡單程序也是如此。 > Tip: `-W`參數告訴 g??o 編譯命令在類型檢查后打印**debug parse tree**。 查看下面兩個命令的輸出: ```shell $ go tool compile -W nodeTree.go | grep before before walk main before walk init $ go tool compile -W nodeTree.go | grep after after walk main after walk init ``` 由以上輸出可以知道,`before`關鍵字是關于函數執行開始的。如果你的程序具有更多功能,你將獲得更多輸出,比如: ```shell $ go tool compile -W defer.go | grep before before d1 before d2 before d3 before main before d2.func1 before d3.func1 before init before type..hash.[2]interface {} before type..eq.[2]interface {} ``` 前面的示例使用`defer.go`的 Go 代碼,該代碼比`nodeTree.go`復雜得多。但是,很顯然,`init()`函數是 Go 自動生成的,因為它也在`go tool compile -W`的兩個輸出中(`nodeTree.go`和`defer.go`)。現在,我將向你展示一個名為`nodeTreeMore.go`輸出,它是一個多版本的`nodeTree.go`: ```Go package main import ( "fmt" ) func functionOne(x int) { fmt.Println(x) } func main() { varOne := 1 varTwo := 2 fmt.Println("Hello there!") functionOne(varOne) functionOne(varTwo) } ``` `nodeTreeMore.go`程序有兩個變量,分別名為`varOne`和`varTwo`,以及一個名為`functionOne`的附加函數。在`go tool compile -W`輸出中搜索`varOne,varTwo`和`functionOne`將顯示以下信息: ```shell $ go tool compile -W nodeTreeMore.go | grep functionOne | uniq before walk functionOne after walk functionOne . . NAME-main.functionOne a(true) l(7) x(0) class(PFUNC) tc(1) used FUNC-func(int) $ go tool compile -W nodeTreeMore.go | grep varTwo | uniq . . NAME-main.varTwo a(true) g(2) l(13) x(0) class(PAUTO) tc(1) used int . . . NAME-main.varTwo a(true) g(2) l(13) x(0) class(PAUTO) tc(1) used int $ go tool compile -W nodeTreeMore.go | grep varOne | uniq . . NAME-main.varOne a(true) g(1) l(12) x(0) class(PAUTO) tc(1) used int . . . NAME-main.varOne a(true) g(1) l(12) x(0) class(PAUTO) tc(1) used int ``` 因此,`varOne`表示為`NAME-main.varOne`,而`varTwo`表示為`NAME-main.varTwo`。 `functionOne()`函數被稱為`NAME-main.functionOne`,`main()`函數被表示為`NAME-main`。 現在,讓我們看看`nodeTreeMore.go`的 debug parse tree: ```shell before walk functionOne . AS l(8) tc(1) . . NAME-main..autotmp_2 a(true) l(8) x(0) class(PAUTO) esc(N) tc(1) assigned used int . . NAME-main.x a(true) g(1) l(7) x(0) class(PPARAM) tc(1) used int ``` 這段信息與`functionOne()`的定義有關。 `l(8)`字符串告訴我們,可以在第八行(即在讀取第七行之后)找到該節點的定義。 `NAME-main..autotmp_2`整數變量由編譯器自動生成。 debug parse tree 輸出的下一部分將在此處進行說明: ```shell . CALLFUNC l(15) tc(1) . . NAME-main.functionOne a(true) l(7) x(0) class(PFUNC) tc(1) used FUNC-func(int) . CALLFUNC-list . . NAME-main.varOne a(true) g(1) l(12) x(0) class(PAUTO) tc(1) used int ``` 第一行說在程序的第15行(由`l(15)`指定),你將調用`NAME-main.functionOne`,該名稱在程序的第7行定義,由`l(7)`指定,即一個需要一個整數參數的函數,該函數由`FUNC func(int)`指定。在`CALLFUNC-list`之后指定的參數函數列表包括`NAME-main.varOne`變量,該變量在程序的第12行定義,如`l(12)`所示。
                  <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>

                              哎呀哎呀视频在线观看