站長資訊網
        最全最豐富的資訊網站

        go generate命令的作用是什么

        “go generate”命令的作用是在編譯前自動化生成某類代碼;它常用于自動生成代碼,它可以在代碼編譯之前根據源代碼生成代碼。當運行“go generate”命令時,它將掃描與當前包相關的源代碼文件,找出所有包含“//go:generate”的特殊注釋,提取并執行該特殊注釋后面的命令。

        go generate命令的作用是什么

        本教程操作環境:windows7系統、GO 1.18版本、Dell G3電腦。

        Go語言提供了一系列強大的工具,靈活使用這些工具,能夠讓我們的項目開發更加容易,工具集包含如下。

        bug         start a bug report build       compile packages and dependencies clean       remove object files and cached files doc         show documentation for package or symbol env         print Go environment information fix         update packages to use new APIs fmt         gofmt (reformat) package sources generate    generate Go files by processing source get         add dependencies to current module and install them install     compile and install packages and dependencies list        list packages or modules mod         module maintenance run         compile and run Go program test        test packages tool        run specified go tool version     print Go version vet         report likely mistakes in packages
        登錄后復制

        工具的源碼位于$GOPATH/src/cmd/internal,本篇文章主要討論Go工具generate。

        go語言自動化工具


        go generate命令是在Go語言 1.4 版本里面新添加的一個命令,常用于自動生成代碼,它可以在代碼編譯之前根據源代碼生成代碼。當運行go generate時,它將掃描與當前包相關的源代碼文件,找出所有包含"// go:generate"的注釋語句,提取并執行該注釋后的命令,命令為可執行程序。該過程類似于調用執行shell腳本。

        使用方法

        • 添加特殊注釋

        //go:generate command argument...
        登錄后復制

        • 執行generate命令

        $ go generate [-run regexp] [-n] [-v] [-x] [build flags] [file.go... | packages]
        登錄后復制

        注意事項

        • 該特殊注釋必須包含在.go源碼文件中。
        • 每個源碼文件可以包含多個generate特殊注釋。
        • go generate不會被類似go build,go get,go test等命令觸發執行,必須由開發者顯式使用。
        • 命令執行是串行的,如果出錯,后續命令不再執行。
        • 特殊注釋必須以“//go:generate”開頭,雙斜線之后沒有空格。
        • 執行命令必須是系統PATH(echo $PATH)下的可執行程序。

        使用示例

        package mainimport "fmt"//go:generate echo GoGoGo!//go:generate go run main.go//go:generate echo $GOARCH $GOOS $GOFILE $GOLINE $GOPACKAGEfunc main() {  fmt.Println("go rum main.go!")}
        登錄后復制

        執行go generate命令

        $ go generate GoGoGo!go rum main.go!amd64 darwin main.go 7 main
        登錄后復制

        為枚舉常量實現String方法


        看完上述generate的簡單介紹,可能讀者并沒有感受到該工具的強大之處,小菜刀提供一個該工具的經典應用場景:為枚舉常量實現String方法。

        這里需要提及官方的另外一個工具stringer,它可以自動為整數常量集編寫String()方法。由于stringer并不在Go官方發行版的工具集里,我們需要自行安裝,執行如下命令。

        go get golang.org/x/tools/cmd/stringer
        登錄后復制

        這里引用stringer文檔中的一個示例。代碼如下,其定義了一組不同Pill類型的整數常量。

        package painkillertype Pill intconst (     Placebo Pill = iota     Aspirin     Ibuprofen     Paracetamol     Acetaminophen = Paracetamol)
        登錄后復制

        為了進行調試或者其他原因,我們希望這些常量能夠打印出來,這意味著Pill要有一個帶有簽名的方法。

        func (p Pill) String() string
        登錄后復制

        要實現它,非常簡單。

        func (p Pill) String() string {     switch p {     case Placebo:         return "Placebo"     case Aspirin:         return "Aspirin"     case Ibuprofen:         return "Ibuprofen"     case Paracetamol: // == Acetaminophen         return "Paracetamol"     }     return fmt.Sprintf("Pill(%d)", p)}
        登錄后復制

        試想,如果我們的Pill名單里新增了一批藥品名,每次增加或修改藥品名,在相應的簽名函數里,也都需要進行更改。這樣豈不是很麻煩且很可能遺漏或出錯?這時,我們可以通過 go generate + stringer的方案解決該問題。很簡單,只需在定義Pill的代碼中,增加一句注釋語句即可。

        //go:generate stringer -type=Pill
        登錄后復制

        上面的命令,代表運行stringer工具來為Pill類型生成String方法,默認輸出到pill_string.go文件中,執行如下。

        $ go generate $ cat pill_string.go // Code generated by stringer -type Pill pill.go; DO NOT EDIT.  package painkillerimport "fmt"const _Pill_name = "PlaceboAspirinIbuprofenParacetamol"var _Pill_index = [...]uint8{0, 7, 14, 23, 34}func (i Pill) String() string {     if i < 0 || i+1 >= Pill(len(_Pill_index)) {         return fmt.Sprintf("Pill(%d)", i)     }     return _Pill_name[_Pill_index[i]:_Pill_index[i+1]]}
        登錄后復制

        這樣,每次我們對Pill類型有修改時,我們所需要做的就是運行以下語句即可。

        $ go generate
        登錄后復制

        當然,你要是覺得這樣麻煩,或者擔心忘記執行generate語句。那么,可以將go generate語句寫入Makefile之中,置于go build命令之前,實現代碼生成與編譯的自動化。

        值得一提的是,在Go源碼文檔中,大量采用了go generate+stringer的方案實現對枚舉常量的String方法。在小菜刀本機Go 1.14.1的源碼下,一共有23處使用,具體如下。

        go generate命令的作用是什么

        總結


        本文主要介紹generate是什么,能做什么,如果想深入理解其內在實現邏輯,可以去看Go源碼中生成代碼的詳細過程,例如sort包下通過genzfunc.go實現zfuncversion.go的生成。在Go源碼寶庫中,可以找到很多相似的實現邏輯,參照如下。

        go generate命令的作用是什么

        它們利用Go編譯器提供的庫,包括定義抽象語法樹的 go/ast、解析抽象語法樹的go/parser、解析用于格式化代碼的 go/format、用于Go詞法標記的go/token等。解析源文件并按照已有的模板生成新的代碼,這一過程和Web 服務中利用模板生成 HTML 文件類似。

        贊(0)
        分享到: 更多 (0)
        網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
        主站蜘蛛池模板: 麻豆精品| 国产精品亚洲аv无码播放| 亚洲精品无码不卡在线播放HE| 欧美日韩精品一区二区三区| 少妇人妻偷人精品视频| 久久精品国产黑森林| 四虎永久在线精品国产免费 | 中文字幕精品一区二区精品| 国产精品videossex白浆| 成人精品综合免费视频| 无码精品人妻一区二区三区免费看 | 亚洲?V无码乱码国产精品| 93精91精品国产综合久久香蕉| 国产成人精品一区二区三区免费| 亚洲日韩国产AV无码无码精品| 国产午夜精品一区二区三区小说| 91精品国产色综久久| 青青青青久久精品国产h| 欧美精品华人在线| 久久精品国产一区二区三区日韩| 999久久久免费精品国产| 国产精品无圣光一区二区| 国精无码欧精品亚洲一区| 久久青青草原精品国产 | 精品一区二区三区免费观看 | AAA级久久久精品无码片| 日本内射精品一区二区视频 | 国产午夜福利精品久久| Xx性欧美肥妇精品久久久久久| 青青草国产精品欧美成人| 91国内揄拍国内精品对白不卡 | 中文字幕日韩精品有码视频 | 99熟女精品视频一区二区三区 | 无码国模国产在线无码精品国产自在久国产| 国内精品久久久久久久久| 国产在线精品一区免费香蕉| 精品91自产拍在线观看| 久久精品国产99久久香蕉| 亚洲av无码国产精品色在线看不卡| 欧美精品整片300页| 亚洲福利精品电影在线观看|