Go 语言基础工具库,避免重复开发。
| 模块 | 一句话定位 |
|---|---|
| webx | HTTP 客户端封装,Functional Options 模式 |
| loom.Go() | 启动带自动资源回收的协程(Ticker/Timer 自动 Stop) |
| convert | JSON 序列化/反序列化 + 字节大小格式化 + 类型转换 |
基于 Functional Options 模式的 HTTP 请求工具,支持 GET/POST/自定义 Method。
func Get(ctx context.Context, url string, options ...Option) ([]byte, error)
func Post(ctx context.Context, url string, options ...Option) ([]byte, error)
func Request(ctx context.Context, method string, url string, options ...Option) ([]byte, error)
// Options
func WithRequestBuilder(builder func(request *http.Request) string) Option
func WithClient(client *http.Client) OptionGET 请求带查询参数:
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
result, err := webx.Get(ctx, "https://httpbin.org/get", webx.WithRequestBuilder(func(req *http.Request) string {
query := req.URL.Query()
query.Add("key", "value")
return query.Encode()
}))POST application/x-www-form-urlencoded:
result, err := webx.Post(context.Background(), url, webx.WithRequestBuilder(func(req *http.Request) string {
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
query := req.URL.Query()
query.Add("key", "value")
return query.Encode()
}))POST application/json:
result, err := webx.Post(context.Background(), url, webx.WithRequestBuilder(func(req *http.Request) string {
req.Header.Set("Content-Type", "application/json")
return `{"name": "panda"}`
}))自定义 HTTP 客户端(连接池配置等):
client := &http.Client{Transport: &http.Transport{MaxIdleConns: 100}}
result, err := webx.Get(ctx, url, webx.WithClient(client))启动一个协程,自动管理 Ticker/Timer 的生命周期:协程退出时自动 Stop 所有通过 Later 创建的 Ticker 和 Timer,并捕获 panic 写入日志。
func Go(handler func(later Later))
// Later 接口(在 handler 参数中使用)
type Later interface {
NewTicker(d time.Duration) *LaterTicker
NewTimer(d time.Duration) *LaterTimer
}
// LaterTicker 嵌入了 time.Ticker,额外支持 IsStopped()
// LaterTimer 嵌入了 time.Timer,额外支持 Reset(d) 和 IsStopped()type MyService struct {
wc loom.WaitClose
}
func (my *MyService) Start() {
loom.Go(my.goLoop)
}
func (my *MyService) goLoop(later loom.Later) {
ticker := later.NewTicker(time.Second)
timer := later.NewTimer(5 * time.Second)
for {
select {
case <-ticker.C:
// 每秒执行
case <-timer.C:
timer.Reset(randx.Duration(0, 3*time.Second))
// 不定时间隔执行
case <-my.wc.C():
return // 退出时,ticker 和 timer 自动 Stop
}
}
}JSON 序列化/反序列化的便捷封装,支持通过 InitJson 注入自定义实现(如 sonic、jsoniter)。
// JSON 序列化
func ToJson(v any) []byte // 忽略错误
func ToJsonE(v any) ([]byte, error) // 返回错误
func ToJsonS(v any) string // 返回 string
// JSON 反序列化
func FromJson(data []byte, v any) // 忽略错误
func FromJsonE(data []byte, v any) error // 返回错误
func FromJsonS(data string, v any) // string 输入
// 注入自定义 JSON 实现(如 sonic、jsoniter)
func InitJson(marshal func(v any) ([]byte, error), unmarshal func(data []byte, v any) error)
// 字节大小格式化(如 1073741824 → "1.00G")
func ToHuman(num uint64) string
// 整数追加到 []byte
func AppendInt(b []byte, v any, base int) []byte
// string ↔ []byte 零拷贝转换
func String(b []byte) string
func Bytes(s string) []byteJSON 基本用法:
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
// 序列化
data := convert.ToJsonS(User{Name: "test", Age: 20})
// data == `{"name":"test","age":20}`
// 反序列化
var user User
convert.FromJsonS(data, &user)
// user.Name == "test", user.Age == 20
// 需要错误处理时用 E 后缀版本
bts, err := convert.ToJsonE(user)
err = convert.FromJsonE(bts, &user)注入自定义 JSON 实现:
import jsoniter "github.com/json-iterator/go"
var json2 = jsoniter.ConfigCompatibleWithStandardLibrary
convert.InitJson(json2.Marshal, json2.Unmarshal)字节大小格式化:
convert.ToHuman(0) // "0B"
convert.ToHuman(1023) // "1023B"
convert.ToHuman(1024) // "1.00K"
convert.ToHuman(1048576) // "1.00M"
convert.ToHuman(1073741824) // "1.00G"