在这个例子中解释去生成 [英] Explain go generate in this example

查看:49
本文介绍了在这个例子中解释去生成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在理解去生成时遇到困难.我也几乎找不到与 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆