为了账号安全,请及时绑定邮箱和手机立即绑定

在这个例子中解释 go generate

在这个例子中解释 go generate

Go
月关宝盒 2022-01-10 17:45:49
我很难理解go generate。我也发现几乎没有任何与go generate.请go generate在以下示例中进行说明:package mainimport (        "gopkg.in/mgo.v2"        "gopkg.in/mgo.v2/bson")// --- Addresstype Address struct {        Id            bson.ObjectId `bson:"_id,omitempty"`        AccountId     string        `bson:"account_id"`        Name          string        `bson:"name"`        StreetAddress string        `bson:"streetaddress"`        Town          string        `bson:"town"`        Country       string        `bson:"country"`}// --- AddressHandlertype AddressHandler struct {        MS *mgo.Session}func NewAddressHandler(ms *mgo.Session) *AddressHandler {        return &AddressHandler{MS: ms.Clone()}}func (h *AddressHandler) Close() {        h.MS.Close()}// Addtype AddAddressInput struct {        Address *Address}type AddAddressOutput struct {        Error error}func (h *AddressHandler) AddAddress(in *AddAddressInput, out *AddAddressOutput) {        ms := h.MS.Copy()        defer ms.Close()        c := ms.DB("").C("address")        out.Error = c.Insert(in.Address)}// Removetype RemoveAddressInput struct {        AddressId string}type RemoveAddressOutput struct {        Error error}func (h *AddressHandler) RemoveAddress(in *RemoveAddressInput, out *RemoveAddressOutput) {        ms := h.MS.Copy()        defer ms.Close()        c := ms.DB("").C("address")        out.Error = c.RemoveId(bson.ObjectIdHex(in.AddressId))}// Updatetype UpdateAddressInput struct {        Address *Address}type UpdateAddressOutput struct {        Error error}func (h *AddressHandler) UpdateAddress(in *UpdateAddressInput, out *UpdateAddressOutput) {        ms := h.MS.Copy()        defer ms.Close()        c := ms.DB("").C("address")        out.Error = c.UpdateId(in.Address.AccountId)}// GetAllByAccounttype GetAddressInput struct {        AccountId string}type GetAddressOutput struct {        Address []*Address        Error   error}我想创建这个尚未模板代码的几乎副本。
查看完整描述

1 回答

?
PIPIONE

TA贡献1829条经验 获得超9个赞

我不是 go generate 方面的专家,但是 AFAIK,调用 go generate 来执行可构建的 go 文件中指定的命令,通常是为了产生新的东西。


为搜索特定指令的文件生成扫描://go:generate如果找到,它将执行它后面的命令。


为了更好地理解发生了什么,让我们举一个简单的例子:一个模板 go 文件将有一个要替换的字符串。


示例 1

让我们创建一个命令,将模板字符串 , 替换为NAME另一个字符串AkiRoss:


repl.sh

#!/usr/bin/sh

sed "s/NAME/AkiRoss/g" $1 > $2

下面是 go 模板,注意指令:


模板.go

package main


import "fmt"


//go:generate ./repl.sh $GOFILE aki_$GOFILE


func main() {

    fmt.Println("Hello,", NAME)

}

为方便起见,这两个文件都在同一个目录中,并且 repl.sh 是可执行的。如果我go generate在目录中运行,go工具会调用repl.sh templ.go aki_templ.go,$GOFILE扩展为generate处理的文件名。


这是我得到的:


aki_templ.go

package main


import "fmt"


//go:generate ./repl.sh $GOFILE aki_$GOFILE


func main() {

        fmt.Println("Hello,", AkiRoss)

}

示例 2

关于您的示例,您需要将//go:generate指令放在某处。但是,该指令很可能包含在不同的文件中,而不是模板文件中,该文件调用替换脚本,类似于我制作的脚本,以生成构建所需的文件。


让我通过更改示例来更好地解释这一点:


repl.sh

#!/usr/bin/sh

sed "s/%NAME%/$3/g" $1 > $2

模板.txt

// This is a template for a go file

package main


import "fmt"


type %NAME% struct {

    foo string

    bar int

}


func (self *%NAME%) Perform() {

    fmt.Println(self.foo, self.bar)

}

main.go

package main


import "fmt"


//go:generate ./repl.sh templ.txt foobar.go FooBar


func main() {

    var fb = FooBar{"AkiRoss", -1}

    fmt.Println("Running!")

    fb.Perform()

}

运行go generate会产生一个新文件


foobar.go

// This is a template for a go file

package main


import "fmt"


type FooBar struct {

        foo string

        bar int

}


func (self *FooBar) Perform() {

        fmt.Println(self.foo, self.bar)

}

这允许现在正确编译主要:


$ go build

$ ./program

Running!

AkiRoss -1

我希望这能澄清。


查看完整回答
反对 回复 2022-01-10
  • 1 回答
  • 0 关注
  • 151 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信