站長(zhǎng)資訊網(wǎng)
        最全最豐富的資訊網(wǎng)站

        go generate命令的作用是什么

        “go generate”命令的作用是在編譯前自動(dòng)化生成某類(lèi)代碼;它常用于自動(dòng)生成代碼,它可以在代碼編譯之前根據(jù)源代碼生成代碼。當(dāng)運(yùn)行“go generate”命令時(shí),它將掃描與當(dāng)前包相關(guān)的源代碼文件,找出所有包含“//go:generate”的特殊注釋?zhuān)崛〔?zhí)行該特殊注釋后面的命令。

        go generate命令的作用是什么

        本教程操作環(huán)境:windows7系統(tǒng)、GO 1.18版本、Dell G3電腦。

        Go語(yǔ)言提供了一系列強(qiáng)大的工具,靈活使用這些工具,能夠讓我們的項(xiàng)目開(kāi)發(fā)更加容易,工具集包含如下。

        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
        登錄后復(fù)制

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

        go語(yǔ)言自動(dòng)化工具


        go generate命令是在Go語(yǔ)言 1.4 版本里面新添加的一個(gè)命令,常用于自動(dòng)生成代碼,它可以在代碼編譯之前根據(jù)源代碼生成代碼。當(dāng)運(yùn)行g(shù)o generate時(shí),它將掃描與當(dāng)前包相關(guān)的源代碼文件,找出所有包含"// go:generate"的注釋語(yǔ)句,提取并執(zhí)行該注釋后的命令,命令為可執(zhí)行程序。該過(guò)程類(lèi)似于調(diào)用執(zhí)行shell腳本。

        使用方法

        • 添加特殊注釋

        //go:generate command argument...
        登錄后復(fù)制

        • 執(zhí)行g(shù)enerate命令

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

        注意事項(xiàng)

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

        使用示例

        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!")}
        登錄后復(fù)制

        執(zhí)行g(shù)o generate命令

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

        為枚舉常量實(shí)現(xiàn)String方法


        看完上述generate的簡(jiǎn)單介紹,可能讀者并沒(méi)有感受到該工具的強(qiáng)大之處,小菜刀提供一個(gè)該工具的經(jīng)典應(yīng)用場(chǎng)景:為枚舉常量實(shí)現(xiàn)String方法。

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

        go get golang.org/x/tools/cmd/stringer
        登錄后復(fù)制

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

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

        為了進(jìn)行調(diào)試或者其他原因,我們希望這些常量能夠打印出來(lái),這意味著Pill要有一個(gè)帶有簽名的方法。

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

        要實(shí)現(xiàn)它,非常簡(jiǎn)單。

        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)}
        登錄后復(fù)制

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

        //go:generate stringer -type=Pill
        登錄后復(fù)制

        上面的命令,代表運(yùn)行stringer工具來(lái)為Pill類(lèi)型生成String方法,默認(rèn)輸出到pill_string.go文件中,執(zhí)行如下。

        $ 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]]}
        登錄后復(fù)制

        這樣,每次我們對(duì)Pill類(lèi)型有修改時(shí),我們所需要做的就是運(yùn)行以下語(yǔ)句即可。

        $ go generate
        登錄后復(fù)制

        當(dāng)然,你要是覺(jué)得這樣麻煩,或者擔(dān)心忘記執(zhí)行g(shù)enerate語(yǔ)句。那么,可以將go generate語(yǔ)句寫(xiě)入Makefile之中,置于go build命令之前,實(shí)現(xiàn)代碼生成與編譯的自動(dòng)化。

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

        go generate命令的作用是什么

        總結(jié)


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

        go generate命令的作用是什么

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

        贊(0)
        分享到: 更多 (0)
        網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)
        主站蜘蛛池模板: 国产在线精品无码二区| 国产精品露脸国语对白| 无码人妻精品一区二区三| 国产精品嫩草影院一二三区入口| 久久夜色撩人精品国产小说| 精品亚洲综合久久中文字幕| 久久精品国产亚洲AV电影| 四虎国产精品成人| 精品人妻少妇嫩草AV无码专区| 华人在线精品免费观看| 久久精品国产亚洲AV无码偷窥| 亚洲第一区精品日韩在线播放| 国产麻豆精品入口在线观看 | 福利姬在线精品观看| 少妇人妻偷人精品免费视频| 日韩福利视频精品专区| 精品久久久久久无码国产| 99久久精品费精品国产 | 亚洲热线99精品视频| 久久久久久极精品久久久| 国产精品亚洲w码日韩中文| 91无码人妻精品一区二区三区L| 精品精品国产自在久久高清| 久久久久久久久无码精品亚洲日韩 | 亚洲AV无码国产精品麻豆天美 | 91精品国产福利在线观看| 人妻精品久久无码区| 正在播放国产精品每日更新| 日本五区在线不卡精品| 久久精品女人天堂AV麻| 精品国产污污免费网站入口在线| 国产高清在线精品一区二区 | 欧美精品/日韩精品/国产精品| 国产精品666| 国产日韩精品在线| 欧美精品黑人巨大在线播放| 欧美精品一区二区三区在线 | 国产精品国产三级国产av品爱网 | 欧美精品一区二区久久| 麻豆国内精品久久久久久 | 国产精品永久久久久久久久久|