不知不觉写 Go 已经快一年了,上线了大大小小好几个项目;心态也经历了几轮变化。

因为我个人大概前五年时间写的是 Java ,中途写过一年多的 Python,所以刚接触到 Go 时的感觉如下图:

既没有 Java 的生态,也没有 Python 这么多语法糖。

写到现在的感觉就是:

这里就不讨论这几门语言谁强谁弱了;重点和大家分享下我们日常开发中所使用到的一些第三方库与工具。

这里我主要将这些库分为两类:

  • 业务开发
  • 基础工具开发

业务开发

首先是业务开发,主要包含了 web、数据库、Redis 等。

Gin ️️️️️

首先是 Gin,一款 HTTP 框架,使用简单、性能优秀、资料众多;你还在犹豫选择哪款框架时,那就选择它吧,基本没错。

当然和它配套的 github.com/swaggo/gin-swagger swagger 工具也是刚需;利用它可以生成 swagger 文档。

GORM ️️️️️

GORM 也没啥好说的,如果你喜欢 orm 的方式操作数据库,那就选它吧;同样的也是使用简单、资料较多。

如果有读写分离需求,也可以使用 GORM 官方提供的插件 https://github.com/go-gorm/dbresolver ,配合 GORM 使用也是非常简单。

errors ️️️️️

Go 语言自身提供的错误处理比较简单,https://github.com/pkg/errors 提供了更强大的功能,比如:

  • 包装异常
  • 包装堆栈等。

常用的有以下 API:

// WithMessagef annotates err with the format specifier.
func WithMessagef(err error, format string, args ...interface{}) error // WithStack annotates err with a stack trace at the point WithStack was called.
func WithStack(err error) error

zorolog ️️️️️

Go 里的日志打印库非常多,日志在日常开发中最好就是存在感低;也就是说性能强(不能影响到业务代码)、使用 API 简单。

"github.com/rs/zerolog/log"
log.Debug().Msgf("OrderID :%s", "12121")

excelize

https://github.com/qax-os/excelize是一个读写 Excel 的库,基本上你能遇到的 Excel 操作它都能实现。

now ️️️️

https://github.com/jinzhu/now 是一个时间工具库:

  • 获取当前的年月日、时分秒。
  • 不同时区支持。
  • 最后一周、最后一个月等。
import "github.com/jinzhu/now"

time.Now() // 2013-11-18 17:51:49.123456789 Mon

now.BeginningOfMinute()        // 2013-11-18 17:51:00 Mon
now.BeginningOfHour() // 2013-11-18 17:00:00 Mon
now.BeginningOfDay() // 2013-11-18 00:00:00 Mon
now.BeginningOfWeek() // 2013-11-17 00:00:00 Sun
now.BeginningOfMonth() // 2013-11-01 00:00:00 Fri
now.BeginningOfQuarter() // 2013-10-01 00:00:00 Tue
now.BeginningOfYear() // 2013-01-01 00:00:00 Tue now.EndOfMinute() // 2013-11-18 17:51:59.999999999 Mon
now.EndOfHour() // 2013-11-18 17:59:59.999999999 Mon
now.EndOfDay() // 2013-11-18 23:59:59.999999999 Mon
now.EndOfWeek() // 2013-11-23 23:59:59.999999999 Sat
now.EndOfMonth() // 2013-11-30 23:59:59.999999999 Sat
now.EndOfQuarter() // 2013-12-31 23:59:59.999999999 Tue
now.EndOfYear() // 2013-12-31 23:59:59.999999999 Tue now.WeekStartDay = time.Monday // Set Monday as first day, default is Sunday
now.EndOfWeek() // 2013-11-24 23:59:59.999999999 Sun

Decimal ️️️️

当业务上需要精度计算时 https://github.com/shopspring/decimal 可以帮忙。

import (
"fmt"
"github.com/shopspring/decimal"
) func main() {
price, err := decimal.NewFromString("136.02") quantity := decimal.NewFromInt(3)
fee, _ := decimal.NewFromString(".035")
taxRate, _ := decimal.NewFromString(".08875") subtotal := price.Mul(quantity) preTax := subtotal.Mul(fee.Add(decimal.NewFromFloat(1))) total := preTax.Mul(taxRate.Add(decimal.NewFromFloat(1))) fmt.Println("Subtotal:", subtotal) // Subtotal: 408.06
fmt.Println("Pre-tax:", preTax) // Pre-tax: 422.3421
fmt.Println("Taxes:", total.Sub(preTax)) // Taxes: 37.482861375
fmt.Println("Total:", total) // Total: 459.824961375
fmt.Println("Tax rate:", total.Sub(preTax).Div(preTax)) // Tax rate: 0.08875
}

基本上你能想到的精度转换它都能做到;配合上 GORM 也可以将 model 字段声明为 decimal 的类型,数据库对应的也是 decimal ,这样使用起来时会更方便。

Amount decimal.Decimal `gorm:"column:amout;default:0.0000;NOT NULL" json:"amout"`

configor ️️️️

https://github.com/jinzhu/configor 是一个配置文件读取库,支持 YAML/JSON/TOML 等格式。

go-cache ️️️

https://github.com/patrickmn/go-cache 是一个类似于 Java 中的 Guava cache,线程安全,使用简单;不需要分布式缓存的简单场景可以考虑。

	c := cache.New(5*time.Minute, 10*time.Minute)
// Set the value of the key "foo" to "bar", with the default expiration time
c.Set("foo", "bar", cache.DefaultExpiration)

copier ️️️

https://github.com/jinzhu/copier 看名字就知道这是一个数据复制的库,与 Java 中的 BeanUtils.copy() 类似;可以将两个字段相同但对象不同的 struct 进行数据复制,也支持深拷贝。

func Copy(toValue interface{}, fromValue interface{}) (err error)

在我们需要一个临时 struct 来存放数据时很有用,特别是一个 struct 中字段非常多时,一个个来回赋值确实有点费手指。

但也要注意不要什么情况都使用,会带来一些弊端:

  • 当删除字段时,不能利用编译器提示。
  • 当一些字段需要额外人工处理时,代码不易阅读。
  • 反射赋值,有一定性能损耗。

总之在业务开发时,还是建议人工编写,毕竟代码是给人看的。

env ️️️

https://github.com/caarlos0/env 这个库可以将我们的环境变量转换为一个 struct.

type config struct {
Home string `env:"HOME"`
} func main() {
cfg := config{}
if err := env.Parse(&cfg); err != nil {
fmt.Printf("%+v\n", err)
} fmt.Printf("%+v\n", cfg)
}

这个在我们打包代码到不同的运行环境时非常有用,利用它可以方便的获取不同环境变量。

user_agent ️️️

https://github.com/mssola/user_agent 是一个格式化 user-agent 的小工具。

当我们需要在服务端收集 user-agen 时可以更快的读取数据。

func main() {
ua := user_agent.New("Mozilla/5.0 (Linux; U; Android 2.3.7; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1") fmt.Printf("%v\n", ua.Mobile()) // => true
fmt.Printf("%v\n", ua.Bot()) // => false
fmt.Printf("%v\n", ua.Mozilla()) // => "5.0"
fmt.Printf("%v\n", ua.Model()) // => "Nexus One"
fmt.Printf("%v\n", ua.Platform()) // => "Linux"
fmt.Printf("%v\n", ua.OS())
}

phonenumbers ️️️

https://github.com/nyaruka/phonenumbers 手机号码验证库,可以不用自己写正则表达式了。

// parse our phone number
num, err := phonenumbers.Parse("6502530000", "US")

基础工具

接下来是一些基础工具库,包含一些主流的存储的客户端、中间件等。

gomonkey ️️️️️

github.com/agiledragon/gomonkey 是一个 mock 打桩工具,当我们写单元测试时,需要对一些非接口函数进行 mock 会比较困难,这时就需要用到它了。

由于它是修改了调用对应函数时机器跳转指令,而 CPU 架构的不同对应的指令也不同,所以在我们使用时还不兼容苹果的 M1 芯片,不过目前应该已经兼容了,大家可以试试。

goconvey ️️️️️

https://github.com/smartystreets/goconvey 也是配合单元测试的库,可以兼容 go test 命令。

  • 提供可视化 web UI。
  • 与 IDE 集成显示单元覆盖率。

dig ️️️️️

https://github.com/uber-go/dig 这是一个依赖注入库,我们这里暂不讨论是否应该使用依赖注入,至少目前我们使用下来还是有几个好处:

  • 所有的对象都是单例。
  • 有一个统一的地方管理对象。
  • 使用时直接传递对象当做参数进来即可(容器会自动注入)。

当然也有一些不太方便的地方:

  • 不熟悉时,一个对象是如何创建的不清楚。
  • 代码不是很好理解。

我们内部有自己开发一个业务框架,其中所有的对象都交由 dig 进行管理,使用起来倒也是比较方便。

cobra ️️️️

https://github.com/spf13/cobra是一个功能强大的命令行工具库,我们用它来实现内部的命令行工具,同时也推荐使用 https://github.com/urfave/cli/ 我个人会更习惯用后者,要简洁一些。

BloomRPC ️️️️

https://github.com/uw-labs/bloomrpc 一个 gRPC 可视化工具,比起自己写 gRPC 客户端的代码那确实是要简单许多。



但也有些小问题,比如精度。如果是 int64 超过了 2^56 服务端拿到的值会发生错误,这点目前还未解决。

redis ️️️️

https://github.com/go-redis/redis/ Redis 客户端,没有太多可说的;发展了许多年,该有的的功能都有了。

elastic ️️️️

https://github.com/olivere/elastic 这也是一个非常成熟的 elasticsearch 库。

resty ️️️️

https://github.com/go-resty/resty/ 一个 http client, 使用起来非常简单:

// Create a Resty Client
client := resty.New()
resp, err := client.R().
EnableTrace().
Get("https://httpbin.org/get")

有点 Python requests 包那味了。

pulsar-client-go ️️️

Pulsar 官方出品的 go 语言客户端,相对于 Java 来说其他语言的客户端几乎都是后娘养的;功能会比较少,同时更新也没那么积极;但却没得选。

go-grpc-middleware ️️️

https://github.com/grpc-ecosystem/go-grpc-middleware 官方提供的 gRPC 中间件,可以自己实现内部的一些鉴权、元数据、日志等功能。

go-pilosa ️️️

https://github.com/pilosa/go-pilosa 是一个位图数据库的客户端,位图数据库的场景应用比较有限,通常是有标签需求时才会用到;比如求 N 个标签的交并补集;数据有一定规模后运营一定会提相关需求;可以备着以备不时之需。

pb ️️️

https://github.com/cheggaaa/pb 一个命令行工具进度条,编写命令行工具时使用它交互会更优雅。

总结

最后我汇总了一个表格,方便查看:

名称 类型 功能 星级
Gin 业务开发 HTTP 框架 ️️️️️
GORM 业务开发 ORM 框架 ️️️️️
errors 业务开发 异常处理库 ️️️️️
zorolog 业务开发 日志库 ️️️️️
excelize 业务开发 Excel相关需求 ️️️️️
now 业务开发 时间处理 ️️️️️
Decimal 业务开发 精度处理 ️️️️️
configor 业务开发 配置文件 ️️️️️
go-cache 业务开发 本地缓存 ️️️
copier 业务开发 数据复制 ️️️️️
env 业务开发 环境变量 ️️️️️
user_agent 业务开发 读取 user-agent ️️️️️
phonenumbers 业务开发 手机号码验证 ️️️️️
gomonkey 基础工具 mock工具 ️️️️
goconvey 基础工具 单测覆盖率 ️️️️
dig 基础工具 依赖注入 ️️️️
cobra 基础工具 命令行工具 ️️️
cli 基础工具 命令行工具 ️️️
BloomRPC 基础工具 gRPC 调试客户端 ️️️
redis 基础工具 Redis 客户端 ️️️
elastic 基础工具 elasticsearch 客户端 ️️️
resty 基础工具 http 客户端 ️️️
pulsar-client-go 基础工具 Pulsar 客户端 ️️️
go-grpc-middleware 基础工具 gRPC 中间件 ️️
go-pilosa 基础工具 pilosa 客户端 ️️️
pb 基础工具 命令行工具进度条 ️️️

星级评分的规则主要是看实际使用的频次。

最后夹带一点私货(其实也谈不上)

文中提到了我们内部有基于以上库整合了一个业务开发框架;也基于该框架上线了大大小小10几个项目,改进空间依然不少,目前还是在快速迭代中。

大概的用法,入口 main.go:





最后截取我在内部的分享就概括了整体的思想--引用自公司一司姓同事

也许我们内部经过多次迭代,觉得有能力开放出来给社区带来一些帮助时也会尝试开源;现阶段就不嫌丑了。

这些库都是我们日常开发最常用到的,也欢迎大家在评论区留下你们常用的库与工具。

Go 日常开发常备第三方库和工具的更多相关文章

  1. ios第三方库和工具类

    下面的是使用苹果电脑后,自己的一下积累吧.有好用的第三方库和工具,肯定会第一时间和大家分享的. 自己平时写的一些分类和工具库 SSTools已经在github上面开始更新了,欢迎大家来指正和补充 一. ...

  2. 基于QT开发的第三方库

    基于Qt开发的第三方库 分类: Qt2014-02-12 11:34 1738人阅读 评论(0) 收藏 举报 QT第三方库   目录(?)[+]   文章来源:http://blog.csdn.net ...

  3. iOS开发常用第三方库

    UI 动画 网络相关 Model 其他 数据库 缓存处理 PDF 图像浏览及处理 摄像照相视频音频处理 响应式框架 消息相关 版本新API的Demo 代码安全与密码 测试及调试 AppleWatch ...

  4. iOS开发之第三方库的学习--hpple的使用

    前言:因为在开发中很可能会遇到html解析,如果后台提供的数据只有html数据,或者开发的app需要从web前端的html里获取数据,就需要html解析工具了. 关于HTML解析库,可以阅读:收集几个 ...

  5. ios开发必备第三方库

    引言 作为iOS开发人员,在开发App的过程中怎么会不使用第三方库呢?相信没有App是不使用第三方库的! 网络库 网络库,这是开发必备,除非你的App玩单机.现在特别火也特别好用的网络库就数AFNet ...

  6. iOS开发——导入第三方库引起的unknown type name 'NSString'

    今天加入SVProgressHUD的第三方库的时候报了24个错误( too many errors emitted, stopping now),都是 expected identifier or ' ...

  7. Android开发——发布第三方库到JitPack上

    前言: 看到大神们的写的第三方控件,比较好用,我们使用的时候直接是在gradle上加上代码就可以使用了,现在到我们写了一个第三方控件,想要别人使用的时候也是直接在gradle加上相关的代码就可以用了, ...

  8. Python安装第三方库文件工具——pip

    Python安装第三方库文件一般使用pip. 1.pip的安装 (1)下载pip 进入https://pypi.python.org/pypi/pip#downloads

  9. iOS开发 引用第三方库出现duplicate symbol时的处理方法

      该篇文章是我自己从我的新浪博客上摘抄过来的, 原文链接为: http://blog.sina.com.cn/s/blog_dcc636350102wat5.html     在iOS开发中, 难免 ...

随机推荐

  1. 获取发布版SHA1和调试版SHA1

    总结 调试版: 常见问题 | 高德地图API (amap.com) 发布版: 首先需要生成签名 Android Studio生成签名文件,自动签名,以及获取SHA1和MD5值_donkor_的博客-C ...

  2. 快乐中秋,SQL小白入门指南

    目录 创建表 最基本的创建 怎么查看一个已经建好的表的信息呢 修改字段 插入数据 修改和删除数据 修改 删除 第一个查询 条件语句 使用age的大小比较,查看大于16岁的学生: 使用多个条件并联,大于 ...

  3. Linux系列(35) - 光盘yum源搭建(2)

    光盘搭建yum源 背景 当前Linux服务器没有网络,yum源下载好了,在光盘中 step-01 挂载光盘 mkdir /mnt/cdrom #建立挂载点 mount /dev/cdrom /mnt/ ...

  4. jmeter5.2版本 配置元件之逻辑控制器详解

    1.简单控制器(Simple Controller) 作用:将多个请求放置在一起,但是没有逻辑上的操作,进行一个简单的分组,一般是由于分组后的请求需要进行统一的某个操作或者存在共同的因素.在简单控制器 ...

  5. 启动docker: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock

    启动docker提示: docker: Got permission denied while trying to connect to the Docker daemon socket at uni ...

  6. php nginx 路径批量配置

    * 假设 E:\upload 作为图片上传的位置 nginx 做web服务 * 创建文件conf.php 放到这个目录下 <?php function handleDir($it, &$ ...

  7. ldirectord

    试想,LVS作为前端负载均衡设备,当后端服务器宕机时,LVS还会把用户请求发送到该服务器上,这对用户体验来说是极其糟糕的,因为用户的请求无法得到处理.那么是否有一种机制,能保证后端服务器的是否正常?或 ...

  8. 三种方法求解最大子区间和:DP、前缀和、分治

    题目 洛谷:P1115 最大子段和 LeetCode:最大子序和 给出一个长度为 \(n\) 的序列 \(a\),选出其中连续且非空的一段使得这段和最大. 挺经典的一道题目,下面分别介绍 \(O(n) ...

  9. Java(21)内部类

    作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15228411.html 博客主页:https://www.cnblogs.com/testero ...

  10. python filter lambda 的使用

    lambda 匿名函数的使用 >>> a=lambda x : x in "1234567890.," >>> a("asd" ...