在这个例子中解释去生成 [英] Explain go generate in this example
问题描述
我在理解去生成
时遇到困难.我也几乎找不到与 go generate
相关的帖子.
I'm having difficulties understanding go generate
. I also find barely any posts dealing with go generate
.
在以下示例中,请说明 go generate
:
please explain go generate
in this following example:
package main
import (
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)
// --- Address
type 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"`
}
// --- AddressHandler
type AddressHandler struct {
MS *mgo.Session
}
func NewAddressHandler(ms *mgo.Session) *AddressHandler {
return &AddressHandler{MS: ms.Clone()}
}
func (h *AddressHandler) Close() {
h.MS.Close()
}
// Add
type 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)
}
// Remove
type 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))
}
// Update
type 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)
}
// GetAllByAccount
type GetAddressInput struct {
AccountId string
}
type GetAddressOutput struct {
Address []*Address
Error error
}
func (h *AddressHandler) GetAddress(in *GetAddressInput, out *GetAddressOutput) {
ms := h.MS.Copy()
defer ms.Close()
c := ms.DB("").C("address")
out.Error = c.Find(bson.ObjectIdHex(in.AccountId)).All(&out.Address)
}
我想创建此模板代码的副本.
I would like to create almost carbon copies of this not yet template code.
模板"代码:
package main
import (
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)
// --- Address
type %Model% struct {
Id bson.ObjectId `bson:"_id,omitempty"`
}
// --- %Model%Handler
type %Model%Handler struct {
MS *mgo.Session
}
func New%Model%Handler(ms *mgo.Session) *%Model%Handler {
return &%Model%Handler{MS: ms.Clone()}
}
func (h *%Model%Handler) Close() {
h.MS.Close()
}
// Add
type Add%Model%Input struct {
%Model% *%Model%
}
type Add%Model%Output struct {
Error error
}
func (h *%Model%Handler) Add%Model%(in *Add%Model%Input, out *Add%Model%Output) {
ms := h.MS.Copy()
defer ms.Close()
c := ms.DB("").C("%Model%")
out.Error = c.Insert(in.%Model%)
}
// Remove %Model%
type Remove%Model%Input struct {
%Model%Id string
}
type Remove%Model%Output struct {
Error error
}
func (h *%Model%Handler) Remove%Model%(in *Remove%Model%Input, out *Remove%Model%Output) {
ms := h.MS.Copy()
defer ms.Close()
c := ms.DB("").C("%Model%")
out.Error = c.RemoveId(bson.ObjectIdHex(in.%Model%Id))
}
// Update
type Update%Model%Input struct {
%Model% *%Model%
}
type Update%Model%Output struct {
Error error
}
func (h *%Model%Handler) Update%Model%(in *Update%Model%Input, out *Update%Model%Output) {
ms := h.MS.Copy()
defer ms.Close()
c := ms.DB("").C("%Model%")
out.Error = c.UpdateId(in.%Model%.AccountId)
}
// GetAllByAccount
type Get%Model%Input struct {
AccountId string
}
type Get%Model%Output struct {
%Model% []*%Model%
Error error
}
func (h *%Model%Handler) Get%Model%(in *Get%Model%Input, out *Get%Model%Output) {
ms := h.MS.Copy()
defer ms.Close()
c := ms.DB("").C("%Model%")
out.Error = c.Find(bson.ObjectIdHex(in.AccountId)).All(&out.%Model%)
}
我需要添加或更改什么,以便可以从该假定的模板开始生成
输出.如您所见,所有 Address
都替换为%Model%
.
What do I need to add or change so I can go generate
output from this supposed template. As you can see everything Address
is replaced with %Model%
.
推荐答案
我不是go generate的专家,但是AFAIK会调用go generate来执行可构建的go文件中指定的命令,通常是为了产生新的东西.
I am not expert with go generate, but AFAIK, go generate is called to perform commands specified in buildable go files, normally with the intent to produce something new.
生成扫描搜索特定指令的文件://go:generate
,如果找到,它将执行其后的命令.
Generate scans for files searching for a specific directive: //go:generate
and, if found, it will execute the command following it.
为了更好地了解正在发生的事情,我们举一个简单的示例:模板go文件将具有要替换的字符串.
To understand better what's happening, let's make a simple example: a template go file will have a string to be replaced.
让我们执行一个命令,用另一个字符串 AkiRoss
替换模板字符串 NAME
:
Let's make a command that replace the template string, NAME
, with another string, AkiRoss
:
#!/usr/bin/sh
sed "s/NAME/AkiRoss/g" $1 > $2
此处遵循go模板,请注意以下指令:
Here follows the go template, note the directive:
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处理的文件的名称.
Both files are in the same directory, for convenience, and repl.sh is executable. If I run go generate
in the directory, the go tool will call repl.sh templ.go aki_templ.go
, being $GOFILE
expanded to be the name of the file processed by generate.
这就是我得到的:
package main
import "fmt"
//go:generate ./repl.sh $GOFILE aki_$GOFILE
func main() {
fmt.Println("Hello,", AkiRoss)
}
示例2
对于您的示例,您需要将//go:generate
指令放置在某处.但是,该指令很可能会包含在另一个文件中,而不是模板文件中,该文件会调用替换脚本(类似于我制作的脚本)来生成构建所需的文件.
Example 2
Regarding your example, you will need to place the //go:generate
directive somewhere. It is likely, however, that the directive will be included in a different file, not the template file, that calls a replacement script, similar to the one I made, to produce a file which is needed for building.
让我通过更改示例更好地解释这一点:
Let me explain this better by changing my example:
#!/usr/bin/sh
sed "s/%NAME%/$3/g" $1 > $2
templ.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
将产生一个新文件
// 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)
}
现在可以正确编译main:
which allows now to compile correctly the main:
$ go build
$ ./program
Running!
AkiRoss -1
我希望这一点得到澄清.
I hope this clarified.
更多详细信息此处,更好的示例是
More details here, and a better example is here.
这篇关于在这个例子中解释去生成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!