mailru/easyjson库的特点就是咱们只须要提供构造体,而后用这些构造体生成编码解码的代码。

示例的我的项目名为elasticsearch/encoding/json

一、创立 models

在我的项目中新建 model 目录,目录中新建两个文件model.goresponse.go,在这两个文件头都增加一行代码生成正文:

//go:generate easyjson -all -snake_case $GOFILE
  • //后不能有空格

models.go:

//go:generate easyjson -all -snake_case $GOFILEpackage modelimport (    "time")type Article struct {    ID        uint    Title     string    Body      string    Published time.Time    Author    *Author}type Author struct {    FirstName string    LastName  string}

response.go:

//go:generate easyjson -all -snake_case $GOFILEpackage modeltype ErrorResponse struct {    Info *ErrorInfo `json:"error,omitempty"`}type ErrorInfo struct {    RootCause []*ErrorInfo    Type      string    Reason    string    Phase     string}type IndexResponse struct {    Index   string `json:"_index"`    ID      string `json:"_id"`    Version int    `json:"_version"`    Result  string}type SearchResponse struct {    Took int64    Hits struct {        Total struct {            Value int64        }        Hits []*SearchHit    }}type SearchHit struct {    Score   float64 `json:"_score"`    Index   string  `json:"_index"`    Type    string  `json:"_type"`    Version int64   `json:"_version,omitempty"`    Source Article `json:"_source"`}

二、欠缺主逻辑代码

main.go:

package mainimport (    "bytes"    "elasticsearch/encoding/json/model"    "fmt"    "math/rand"    "os"    "strconv"    "strings"    "time"    "github.com/elastic/go-elasticsearch/v8"    "github.com/elastic/go-elasticsearch/v8/esapi"    "github.com/fatih/color"    "github.com/mailru/easyjson")var (    out       = color.New(color.Reset)    faint     = color.New(color.Faint)    bold      = color.New(color.Bold)    red       = color.New(color.FgRed)    boldGreen = color.New(color.Bold, color.FgGreen)    boldRed   = color.New(color.Bold, color.FgRed)    articles []model.Article    fnames   []string)func init() {    rand.Seed(time.Now().UnixNano())}func main() {    es, err := elasticsearch.NewDefaultClient()    if err != nil {        fmt.Printf("Error creating the client: %s\n", err)        os.Exit(2)    }    fnames = []string{"Alice", "John", "Mary"}    for i, title := range []string{"One", "Two", "Three", "Four", "Five"} {        articles = append(articles,            model.Article{                ID:        uint(i + 1),                Title:     "Test" + title,                Body:      "Lorem ipsum dolor sit amet, consectetur adipisicing elit",                Published: time.Now().AddDate(i, 0, 0),                Author: &model.Author{                    FirstName: fnames[rand.Intn(len(fnames))],                    LastName:  "Smith",                },            })    }    faint.Println("Indexing articles...")    faint.Println(strings.Repeat("━", 80))    var b bytes.Buffer    for _, a := range articles {        b.Reset()        // 将 article 构造体序列化为 json,json 保留到 buffer 中        if _, err := easyjson.MarshalToWriter(a, &b); err != nil {            red.Println("Error decoding response", err)            continue        }        res, err := es.Index(            "articles",            bytes.NewReader(b.Bytes()),            es.Index.WithDocumentID(strconv.Itoa(int(a.ID))),            // es.Index.WithVersion(-1), // <-- 勾销此正文来触发异样        )        if err != nil {            red.Printf("Error indexing article: %s\n", err)            continue        }        defer res.Body.Close()        if res.IsError() {            printErrorResponse(res)            os.Exit(2)        }        var ir model.IndexResponse        if err := easyjson.UnmarshalFromReader(res.Body, &ir); err != nil {            red.Println("Error decoding response", err)            continue        }        boldGreen.Printf("[%s] ", res.Status())        fmt.Println(            faint.Sprint("result=")+out.Sprint(ir.Result),            faint.Sprint("index=")+out.Sprint(ir.Index),            faint.Sprint("ID=")+out.Sprint(ir.ID),            faint.Sprint("version=")+out.Sprint(ir.Version),        )    }    es.Indices.Refresh(es.Indices.Refresh.WithIndex("articles"))    faint.Println("\nSearching articles...")    faint.Println(strings.Repeat("━", 80))    res, err := es.Search(        es.Search.WithIndex("articles"),        es.Search.WithQuery("one OR two"),        // es.Search.WithQuery("{{{one OR two"), // <-- 勾销此正文来触发异样    )    if err != nil {        red.Printf("Error searching articles: %s\n", err)        os.Exit(2)    }    defer res.Body.Close()    if res.IsError() {        printErrorResponse(res)        os.Exit(2)    }    var sr model.SearchResponse    if err := easyjson.UnmarshalFromReader(res.Body, &sr); err != nil {        red.Println("Error decoding response", err)        os.Exit(2)    }    faint.Printf("[%s] took=%d total=%d\n", res.Status(), sr.Took, sr.Hits.Total.Value)    faint.Println(strings.Repeat("─", 80))    for _, h := range sr.Hits.Hits {        fmt.Println(            out.Sprintf("%s,", strings.Join([]string{h.Source.Author.FirstName, h.Source.Author.LastName}, " ")),            bold.Sprintf("%s", h.Source.Title),            out.Sprintf("(%d)", h.Source.Published.Year()),        )        faint.Println(strings.Repeat("─", 80))    }}// printErrorResponse 解码 es 响应,格式化后打印到终端func printErrorResponse(res *esapi.Response) {    bold.Printf("[%s] ", res.Status())    var e model.ErrorResponse    if err := easyjson.UnmarshalFromReader(res.Body, &e); err != nil {        red.Println("Error decoding response:", err)        return    }    boldRed.Print(e.Info.RootCause[0].Type)    faint.Print(" > ")    fmt.Println(e.Info.RootCause[0].Reason)}

三、生成代码

拉取我的项目中须要的库:

go mod tidy

生成代码:

go generate ./model

之后,model 目录中会多出两个文件:model_easyjson.goresponse_easyjson.go

这两个文件中的代码为 model 中的构造体实现了mailru/easyjson规定的一些接口。

四、运行我的项目

go run main.go
Indexing articles...━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[200 OK] result=updated index=articles ID=1 version=36[200 OK] result=updated index=articles ID=2 version=34[200 OK] result=updated index=articles ID=3 version=34[200 OK] result=updated index=articles ID=4 version=34[200 OK] result=updated index=articles ID=5 version=34Searching articles...━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[200 OK] took=2 total=0────────────────────────────────────────────────────────────────────────────────