本文给大家介绍Go的一个实用技巧,该技巧主要通过go工具实现。
传统写法
大家经常碰到命名错误码、状态码的同时,又要同步写码对应的翻译,有没有感觉很无聊。这里举一个例子:
package main
import "fmt"
// 定义错误码
const (
ERR_CODE_OK = 0 // OK
ERR_CODE_INVALID_PARAMS = 1 // 无效参数
ERR_CODE_TIMEOUT = 2 // 超时
)
// 定义错误码与描述信息的映射
var mapErrDesc = map[int]string{
ERR_CODE_OK: "OK",
ERR_CODE_INVALID_PARAMS: "无效参数",
ERR_CODE_TIMEOUT: "超时",
}
// 根据错误码返回描述信息
func GetDescription(errCode int) string {
if desc, exist := mapErrDesc[errCode]; exist {
return desc
}
return fmt.Sprintf("error code: %d", errCode)
}
func main() {
fmt.Println(GetDescription(ERR_CODE_OK))
}
这是一种重复性操作,没有什么技术含量,另外很可能忘记写映射。我只想写错误码,对应的描述信息直接用注释里的就行,所以这里介绍一下对应的工具。
go generate
go有很多工具,大家可以通过go命令查看。

go generate
是 Go 自带的工具。使用命令go generate
执行。go generate
是利用源代码中的注释工作的。格式如下:
//go:generate command arg1 arg2
这样在同一个目录下执行命令go generate
就会自动运行命令command arg1 arg2
。command
可以是在PATH
中的任何命令,应用非常广泛。配合stringer
命令可以为给定类型生成String
方法,就可以实现我们的想法。
安装stringer
stringer不是Go自带工具,需要手动安装。执行如下命令即可
go get golang.org/x/tools/cmd/stringer
注意点
- 需要配置gomod
- 需要设置好目录,当前目录结构如下
使用
有两种执行方案,
一种是在errcode中,增加注释//go:generate stringer -type ErrCode -linecomment
另一种是直接命令行执行stringer -type ErrCode -linecomment
执行完毕会发现自动生成新文件
关于stringer的命令,大家可以通过stringer -h查看
源码
下面是整个源码:
main.go
package main
import (
"fmt"
"myproject/enum"
)
func main() {
fmt.Println(enum.ERR_CODE_OK)
}
errcode.go
package enum
type ErrCode int64 //错误码
const (
ERR_CODE_OK ErrCode = 0 // OK
ERR_CODE_INVALID_PARAMS ErrCode = 1 // 无效参数
ERR_CODE_TIMEOUT ErrCode = 2 // 超时
)
stringer生成的文件
// Code generated by "stringer -type ErrCode -linecomment"; DO NOT EDIT.
package enum
import "strconv"
func _() {
// An "invalid array index" compiler error signifies that the constant values have changed.
// Re-run the stringer command to generate them again.
var x [1]struct{}
_ = x[ERR_CODE_OK-0]
_ = x[ERR_CODE_INVALID_PARAMS-1]
_ = x[ERR_CODE_TIMEOUT-2]
}
const _ErrCode_name = "OK无效参数超时"
var _ErrCode_index = [...]uint8{0, 2, 14, 20}
func (i ErrCode) String() string {
if i < 0 || i >= ErrCode(len(_ErrCode_index)-1) {
return "ErrCode(" + strconv.FormatInt(int64(i), 10) + ")"
}
return _ErrCode_name[_ErrCode_index[i]:_ErrCode_index[i+1]]
}
执行结果显示如下:
➜ myproject go run main.go OK
总结
使用stringer可以帮我们节省很多时间,除了stringer外,还有gostringer,大家感兴趣可以试一下。
资源
- pkg.go.dev/golang.org/…
- studygolang.com/articles/22…
- blog.csdn.net/weixin_3934…
- blog.golang.org/generate
- docs.google.com/document/d/…
- blog.csdn.net/qq_31362439…
- pkg.go.dev/github.com/…
最后
大家如果喜欢我的文章,可以关注我的公众号(程序员麻辣烫)
我的个人博客为:shidawuhen.github.io/
往期文章回顾:
技术
- Go工具之generate
- Go设计模式(4)-代码编写
- Go单例实现方案
- Go设计模式(4)-代码编写
- Go设计模式(3)-设计原则
- Go设计模式(2)-面向对象分析与设计
- 支付接入常规问题
- HTTP2.0基础教程
- Go设计模式(1)-语法
- MySQL开发规范
- HTTPS配置实战
- Go通道实现原理
- Go定时器实现原理
- HTTPS连接过程
- 限流实现2
- 秒杀系统
- 分布式系统与一致性协议
- 微服务之服务框架和注册中心
- Beego框架使用
- 浅谈微服务
- TCP性能优化
- 限流实现1
- Redis实现分布式锁
- Golang源码BUG追查
- 事务原子性、一致性、持久性的实现原理
- CDN请求过程详解
- 常用缓存技巧
- 如何高效对接第三方支付
- Gin框架简洁版
- InnoDB锁与事务简析
- 算法总结
读书笔记
思考