GO代碼生成代碼小思小試


推進需求

GO 項目,可整體生成一個運行文件到處跑,是極爽之事。但如果有資源文件要得帶着跑,則破壞了這種體驗。

例如下邊這個項目結構,resource 目錄下為資源文件,main.go 中會通過路徑引用到這些資源文件,於是新的需求產生了。

|- hello
----|- resource
---------|- note.txt
----|- main.go

需求推進一步:將資源文件打包至運行文件中,在代碼中仍然使用類似相對路徑的引用方式使用它(這個很重要,使用在概念上保持一致)。

解決方案跟上:把資源文件數據轉換成 GO 代碼中的變量值存儲,並提供函數可根據路徑差數返回相應的數據。這樣一來資源文件就變成了代碼文件,又可以一個運行文件到處跑了。

工具跟進 go-bindata

於是,工具 go-bindata 就來了,它來完成將資源文件變成 GO 代碼的工作。

go get -u github.com/jteeuwen/go-bindata/...
go install

在 hello 項目目錄下執行這個工具,就會生成 -o 指定的 bindata.go 代碼文件。

go-bindata -pkg main -o bindata.go resource/

此時,在 hello 目錄下就多了 bindata.go 代碼文件,然后,在 main.go 中,就可以使用以下方式指定相對路徑參數來取得資源數據。

bs, _ := Asset("resource/note.txt")

生成代碼機制 go generate

有了上述工具,當 note.txt 數據有更新時,就需要使用 go-bindata 工具重新生成代碼文件再編譯,可不可以形成一種專門的機制來規范化這類動作呢?

於是,再進一步,若能如此甚好:

(1)GO 項目的代碼中,能自描述的表明有些相關依賴代碼由需要由工具產生。

(2)支持簡單的方式來完成自描述所表明的操作動作。

於是,go generate 應運而生,來看一下它的大概描述。

go generate 命令是 go 1.4 版新添加的一個命令,它將掃描與當前包相關的源代碼文件,找出所有包含 "//go:generate" 的特殊注釋,提取並執行該特殊注釋后面的命令,命令為可執行程序。

是不是完美的實現了上述兩項訴求。

(1)在源代碼,即 GO 文件中,進行注釋(自描述)即可指定要執行的工具命令。
除了 go-bindata 工具之外,類似的工具定是還有很多。工具抽象出來可認為就是可執行命令,指定命令甚是靈活。

(2)只要執行一條命令,即可自動掃描當前包相關的源代碼文件來完成相應的執行。
這說明,不論有多少個這樣的命令需要執行,它會負責找到並執行。

小小實例,一目了然

開頭項目結構中,main.go 的完整代碼如下:

//go:generate go-bindata -pkg main -o bindata.go resource/
//go:generate go build
//go:generate hello

package main

import (
	"fmt"
)

func main() {
	bs, _ := Asset("resource/note.txt")
	fmt.Println(string(bs))
}

注釋部分即描述了三個動作,完成資源文件代碼生成,編譯與運行命令,當執行 go generate 時,三條命令執行下來運行的結果為顯示 note.txt 中的文本內容。運行效果如下,當修改了 note.txt,執行 go generate,會自動完成重新生成代碼,編譯和運行。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM