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,会自动完成从新生成代码,编译和运行。

相关文章
相关标签/搜索