GO代碼生成代碼小思小試

推動需求

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

例以下邊這個項目結構,resource 目錄下爲資源文件,main.go 中會經過路徑引用到這些資源文件,因而新的需求產生了。github

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

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

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

工具跟進 go-bindata

因而,工具 go-bindata 就來了,它來完成將資源文件變成 GO 代碼的工做。code

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

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

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

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

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

生成代碼機制 go generate

有了上述工具,當 note.txt 數據有更新時,就須要使用 go-bindata 工具從新生成代碼文件再編譯,可不能夠造成一種專門的機制來規範化這類動做呢?get

因而,再進一步,若能如此甚好:string

(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,會自動完成從新生成代碼,編譯和運行。

相關文章
相關標籤/搜索