V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
justmaplewu
V2EX  ›  Go 编程语言

使用 Gozz 自动化管理你的结构体字段标签

  •  
  •   justmaplewu · 2023-10-27 11:16:25 +08:00 · 407 次点击
    这是一个创建于 386 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在 Golang 开发中,我们经常会设计各种各样的结构体,然后给各个字段添加各种各样的标签。

    例如,使用 json:something 来做 JSON 的序列化和反序列化

    package x
    
    type T struct{
      MyField string `json:"my_field"`
    }
    

    众所周知,命名是编程中的两大难事之一,当我们有了这些标签之后,我们会面临额外的一些问题如下:

    • 要使用哪种命名风格 驼峰法 camelCase 还是 蛇形法 snake_case ?
    • 如果使用了 camelCase ,对于像 UserID 这样的,应该使用 userId 还是 userID
    • 结构体的字段数量和字段名都是有可能在后续开发中不断变更地,当这些变更发生时,怎么才能快速按照之前的规则来完成这些结构体的被动变更?
    • 如果你的项目有其他人协作,你要怎么来保证所有的开发者或者新人能够快速理解这些既定的约定,并且不需要额外付出人力校对成本去把控这些规范?

    虽然我们可以在 Lint 阶段或者自动化测试里面去检测这些问题,但是我会更偏向于下面的做法:

    永远不要通过人工来管理这些标签,而是通过工具化去自动化地生成。

    你可以使用 Gozz 来很轻易地实现这个模式:

    下面有个很简单的例子,我们想要填充 jsonbson 两种标签给我们的结构体

    package tag01
    
    // +zz:tag:json,bson:{{ snake .FieldName }}
    type User struct {
    	Id        string
    	Name      string
    	Address   string
    	CreatedAt time.Time
    	UpdatedAt time.Time
    }
    

    只需要在结构体上面加上一个注解 +zz:tag:json,bson:{{ snake .FieldName}}

    然后执行 gozz run -p "tag" ./ 

    你会发现这些问题就会彻底得到解决,代码的标签会被自动化按模版格式填充:

    package tag01
    
    // +zz:tag:json,bson:{{ snake .FieldName }}
    type User struct {
    	Id        string    `bson:"id" json:"id"`
    	Name      string    `bson:"name" json:"name"`
    	Address   string    `bson:"address" json:"address"`
    	CreatedAt time.Time `bson:"created_at" json:"created_at"`
    	UpdatedAt time.Time `bson:"updated_at" json:"updated_at"`
    }
    

    最后 只需要将这些命令放到项目的 Makefile 在进行构建流水线时自动化执行,或者加到 commit hooks里,这些结构体标签的规范从此以后都不需要人工介入。

    上面的例子展示了 gozz-tag 的一些基本功能,下面的例子会额外展示这个工具的一些强大特性:

    • 我们把注解加到了块级的代码定义,结构体的定义,以及字段的定义上
    • 然后对同个 key 使用了不同的模版格式,以及 golang 的模版函数方法
    // +zz:tag:json,bson:{{ snake .FieldName }}
    type (
    	User struct {
    		Id        string
    		Name      string
    		Address   string
    		CreatedAt time.Time
    		UpdatedAt time.Time
    	}
    
    	// +zz:tag:json,bson:{{ camel .FieldName }}
    	Book struct {
    		Id        string
    		Title     string
    		CreatedAt time.Time
    		UpdatedAt time.Time
    	}
    
    	Order struct {
    		Id     string
    		UserId string
    		BookId string
    		// +zz:tag:json,bson:{{ upper .FieldName | upper }}
    		CreatedAt time.Time
    		// +zz:tag:+json:,omitempty
    		UpdatedAt time.Time
    	}
    )
    

    执行 gozz 命令之后 ,文件会被更新为

    // +zz:tag:json,bson:{{ snake .FieldName }}
    type (
    	User struct {
    		Id        string    `bson:"id" json:"id"`
    		Name      string    `bson:"name" json:"name"`
    		Address   string    `bson:"address" json:"address"`
    		CreatedAt time.Time `bson:"created_at" json:"created_at"`
    		UpdatedAt time.Time `bson:"updated_at" json:"updated_at"`
    	}
    
    	// +zz:tag:json,bson:{{ camel .FieldName }}
    	Book struct {
    		Id        string    `bson:"id" json:"id"`
    		Title     string    `bson:"title" json:"title"`
    		CreatedAt time.Time `bson:"createdAt" json:"createdAt"`
    		UpdatedAt time.Time `bson:"updatedAt" json:"updatedAt"`
    	}
    
    	Order struct {
    		Id     string `bson:"id" json:"id"`
    		UserId string `bson:"user_id" json:"user_id"`
    		BookId string `bson:"book_id" json:"book_id"`
    		// +zz:tag:json,bson:{{ snake .FieldName | upper }}
    		CreatedAt time.Time `bson:"CREATED_AT" json:"CREATED_AT"`
    		// +zz:tag:+json:,omitempty
    		UpdatedAt time.Time `bson:"updated_at" json:"updated_at,omitempty"`
    	}
    )
    

    需求都被完美解决了。

    所以,相信在 Gozz 的帮助下,我们已经不需要去人工地维护这些结构体的标签规范了,只需要把注解加在定义块上,然后把生成的命令放到开发流水线中。

    实际上,这个功能只是 Gozz 其中一个内置插件,它还提供了很多其他强大的插件,可以帮我们借助注解去做很多更强大的事情,比如 自动化的依赖注入、API 路由的自动生成 还有 ORM 结构体的生成。

    更多详情可以去 github 或者 中文文档 查看,也欢迎给我们点一个 ⭐️。

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2602 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 04:48 · PVG 12:48 · LAX 20:48 · JFK 23:48
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.