本文给大家介绍Go的一个实用技巧,该技巧主要通过go工具实现。
1.传统写法
大家经常碰到命名错误码、状态码的同时,又要同步写码对应的翻译,有没有感觉很无聊。这里举一个例子:
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))
}
这是一种重复性操作,没有什么技术含量,另外很可能忘记写映射。我只想写错误码,对应的描述信息直接用注释里的就行,所以这里介绍一下对应的工具。
2.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方法,就可以实现我们的想法。
2.1安装stringer
stringer不是Go自带工具,需要手动安装。执行如下命令即可
go get golang.org/x/tools/cmd/stringer
2.2注意点
- 需要配置gomod
- 需要设置好目录,当前目录结构如下
2.3使用
有两种执行方案,
一种是在errcode中,增加注释//go:generate stringer -type ErrCode -linecomment
另一种是直接命令行执行stringer -type ErrCode -linecomment
执行完毕会发现自动生成新文件
关于stringer的命令,大家可以通过stringer -h查看
3.源码
下面是整个源码:
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
4.总结
使用stringer可以帮我们节省很多时间,除了stringer外,还有gostringer,大家感兴趣可以试一下。
资源
- https://pkg.go.dev/golang.org/x/tools#readme-go-tools
- https://studygolang.com/articles/22984?fr=sidebar
- https://blog.csdn.net/weixin_39345003/article/details/109307880
- https://blog.golang.org/generate
- https://docs.google.com/document/d/1V03LUfjSADDooDMhe-_K59EgpTEm3V8uvQRuNMAEnjg/edit#heading=h.j6dsjy94dn2q
- https://blog.csdn.net/qq_31362439/article/details/105163641
- https://pkg.go.dev/github.com/sourcegraph/gostringer
最后
大家如果喜欢我的文章,可以关注我的公众号(程序员麻辣烫)
我的个人博客为:https://shidawuhen.github.io/
往期文章回顾:
技术
- 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锁与事务简析
- 算法总结
读书笔记
- 原则
- 资治通鉴
- 敏捷革命
- 如何锻炼自己的记忆力
- 简单的逻辑学-读后感
- 热风-读后感
- 论语-读后感
- 孙子兵法-读后感
思考
- 反对自由主义
- 实践论
- 评价自己的标准
- 服务端团队假期值班方案
- 项目流程管理
- 对项目管理的一些看法
- 对产品经理的一些思考
- 关于程序员职业发展的思考
- 关于代码review的思考
- Markdown编辑器推荐-typora