【Golang】关于Golang中一些优秀的类库
一、CLI 命令(spf13/cobra)
GitHub地址:https://github.com/spf13/cobra
Cobra既是一个创建强大的现代CLI应用程序的库,也是一个生成应用程序和命令的程序。可以使用这个库来管理命令应用程序,执行runner应用程序,初始化配置,病启动Reast API。
基于Cobra的应用的目录结构:
1 2 3 4 5 6 | ├── app │ ├── main. go │ ├── cmd │ └────── root. go │ └────── helper. go │ └────── version. go |
在 app/main.go 中:
1 2 3 4 5 6 7 8 9 | package main import ( "app/cmd" ) func main() { cmd.Execute() } |
在 app/cmd/root.go 中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | package cmd import ( "errors" "github.com/spf13/cobra" ) var rootCmd = &cobra.Command{ Use: "git" , Short: "Git is a distributed version control system." , Long: `Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency.`, Run: func (cmd *cobra.Command, args []string) { Error(cmd, args, errors.New( "unrecognized command" )) }, } func Execute() { rootCmd.Execute() } |
在 app/cmd/helper.go 中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | package cmd import ( "fmt" "github.com/spf13/cobra" "os" "os/exec" ) func ExecuteCommand(name string, subname string, args ...string) (string, error) { args = append([]string{subname}, args...) cmd := exec.Command(name, args...) bytes, err := cmd.CombinedOutput() return string(bytes), err } func Error(cmd *cobra.Command, args []string, err error) { fmt.Fprintf(os.Stderr, "execute %s args:%v error:%v\n" , cmd.Name(), args, err) os.Exit(1) } |
在 app/cmd/version.go 中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | package cmd import ( "fmt" "github.com/spf13/cobra" "os" ) var versionCmd = &cobra.Command{ Use: "version" , Short: "version subcommand show git version info." , Run: func (cmd *cobra.Command, args []string) { output, err := ExecuteCommand( "git" , "version" , args...) if err != nil { Error(cmd, args, err) } fmt.Fprint(os.Stdout, output) }, } func init() { rootCmd.AddCommand(versionCmd) } |
开始运行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | PS G:\ go -demo\test11> go run main. go --help Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency. Usage: git [flags] git [command] Available Commands: completion Generate the autocompletion script for the specified shell help Help about any command version version subcommand show git version info. Flags: -h, --help help for git Use "git [command] --help" for more information about a command. |
二、ORM:Gorm
GitHub地址:https://github.com/go-gorm/gorm/推荐理由:代码优雅,场景非常丰富,满足我们的SQL场景需求,比如:
- 全功能ORM
- 关联(拥有一个、拥有多个、属于、多对多、多态、单表继承)
- Create,Save,Update,Delete,Find 中钩子方法
- 支持 Preload、Joins 的预加载
- 事务,嵌套事务,Save Point,Rollback To to Saved Point
- Context、预编译模式、DryRun 模式
- 批量插入,FindInBatches,Find/Create with Map,使用 SQL 表达式、Context Valuer 进行 CRUD
- SQL 构建器,Upsert,锁,Optimizer/Index/Comment Hint,命名参数,子查询
- 复合主键,索引,约束
- 自动迁移
- 自定义 Logger
- 灵活的可扩展插件 API:Database Resolver(多数据库,读写分离)、Prometheus…
- 每个特性都经过了测试的重重考验
三、SQL(jmoiron/sqlx)
GitHub地址:https://github.com/jmoiron/sqlx
是sqlx的一个库,在Go的标准database/sql库上提供了一组扩展。
示例:
1 2 3 4 5 6 7 8 9 | place := Place{} rows, err := db.Queryx( "SELECT * FROM place" ) for rows.Next() { err := rows.StructScan(&place) if err != nil { log.Fatalln(err) } fmt.Printf( "%#v\n" , place) } |
四、配置管理:viper
GitHub地址:https://github.com/spf13/viper
- 支持JSON/TOML/YAML/HC:/en:L/envfile/Java properties等多种格式的配置文件;
- 可以设置监听配置文件的修改,修改时自动加载新的配置;
- 从环境变量、命令行选项和io。Reader中读取配置;
- 从远程配置系统中读取和监听修改,如etcd/Consu;
- 代码逻辑中显示设置键值
五、日志管理:zap
GitHub地址::GitHub - uber-go/zap: Blazing fast, structured, leveled logging in Go.
1 2 3 4 5 6 7 8 9 10 | logger, _ := zap.NewProduction() defer logger.Sync() // flushes buffer, if any sugar := logger.Sugar() sugar.Infow( "failed to fetch URL" , // Structured context as loosely typed key-value pairs. "url" , url, "attempt" , 3, "backoff" , time.Second, ) sugar.Infof( "Failed to fetch URL: %s" , url) |
六、消息队列 asynq
Github地址: GitHub - hibiken/asynq: Simple, reliable, and efficient distributed task queue in Go
可靠、简单、高效的分布式任务队列。
七、消息传递 NSQ
GitHub地址:https://github.com/nsqio/go-nsq
NSQ 拓扑

NSQ 组件:
- nsqlookupd (守护进程管理拓扑 / 路由)
- nsqd(守护进程管理接收、排队和传递消息)
- nsqadmin(nsq 的默认 Web UI)
docker-compose 示例:(nsqlookupd, nsqd, nsqadmin)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | version: '3' services: nsqlookupd: image: nsqio/nsq command: /nsqlookupd ports: - "4160:4160" - "4161:4161" nsqd: image: nsqio/nsq command: /nsqd --lookupd-tcp-address=nsqlookupd:4160 depends_on: - nsqlookupd ports: - "4150:4150" - "4151:4151" nsqadmin: image: nsqio/nsq command: /nsqadmin --lookupd-http-address=nsqlookupd:4161 depends_on: - nsqlookupd ports: - "4171:4171" |
执行:
1 2 3 4 5 6 7 8 9 10 | 运行 docker: $ docker-compose up -d 或者,如果使用名称 (docker-compose-nsq.yml): $ docker-compose -f docker-compose-nsq.yml up -d 检查容器 docker: $ docker-compose ps 查看日志: $ docker-compose logs 检查 nsq Web UI(假设端口为 32770): $ curl http: //127.0.0.1:32770/ping |
目录结构:
1 2 3 4 | ├── consume │ └── consume. go └── publish └── publish. go |
consume.go:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package main import ( "github.com/nsqio/go-nsq" "log" "sync" ) func main() { wg := &sync.WaitGroup{} wg.Add(1) decodeConfig := nsq.NewConfig() c, err := nsq.NewConsumer( "My_NSQ_Topic" , "My_NSQ_Channel" , decodeConfig) if err != nil { log.Panic( "Could not create consumer" ) } c.AddHandler(nsq.HandlerFunc( func (message *nsq.Message) error { log.Println( "NSQ message received:" ) log.Println(string(message.Body)) return nil })) err = c.ConnectToNSQD( "127.0.0.1:4150" ) if err != nil { log.Panic( "Could not connect" ) } log.Println( "Awaiting messages from NSQ topic \"My NSQ Topic\"..." ) wg.Wait() } |
运行 consume.go:
1 | $ go run consume/consume. go |
publish.go:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | package main import ( "log" "github.com/nsqio/go-nsq" ) func main() { config := nsq.NewConfig() p, err := nsq.NewProducer( "127.0.0.1:4150" , config) if err != nil { log.Panic(err) } err = p.Publish( "My_NSQ_Topic" , []byte( "sample NSQ message" )) if err != nil { log.Panic(err) } } |
运行 publish.go:
1 | $ go run publish/publish. go |
八、JSON校验库
-
golang json 校验库
GitHub地址:https://github.com/go-playground/validator
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | package main import ( "fmt" "github.com/go-playground/validator/v10" ) // User contains user information type User struct { FirstName string `validate: "required" ` LastName string `validate: "required" ` Age uint8 `validate: "gte=0,lte=130" ` Email string `validate: "required,email" ` FavouriteColor string `validate: "iscolor" ` // alias for 'hexcolor|rgb|rgba|hsl|hsla' Addresses []*Address `validate: "required,dive,required" ` // a person can have a home and cottage... } // Address houses a users address information type Address struct { Street string `validate: "required" ` City string `validate: "required" ` Planet string `validate: "required" ` Phone string `validate: "required" ` } // use a single instance of Validate, it caches struct info var validate *validator.Validate func main() { validate = validator.New() validateStruct() validateVariable() } func validateStruct() { address := &Address{ Street: "Eavesdown Docks" , Planet: "Persphone" , Phone: "none" , } user := &User{ FirstName: "Badger" , LastName: "Smith" , Age: 135, Email: "Badger.Smith@gmail.com" , FavouriteColor: "#000-" , Addresses: []*Address{address}, } // returns nil or ValidationErrors ( []FieldError ) err := validate.Struct(user) if err != nil { // this check is only needed when your code could produce // an invalid value for validation such as interface with nil // value most including myself do not usually have code like this. if _, ok := err.(*validator.InvalidValidationError); ok { fmt.Println(err) return } for _, err := range err.(validator.ValidationErrors) { fmt.Println(err.Namespace()) fmt.Println(err.Field()) fmt.Println(err.StructNamespace()) fmt.Println(err.StructField()) fmt.Println(err.Tag()) fmt.Println(err.ActualTag()) fmt.Println(err.Kind()) fmt.Println(err.Type()) fmt.Println(err.Value()) fmt.Println(err.Param()) fmt.Println() } // from here you can create your own error messages in whatever language you wish return } // save user to database } func validateVariable() { myEmail := "joeybloggs.gmail.com" errs := validate.Var(myEmail, "required,email" ) if errs != nil { fmt.Println(errs) // output: Key: "" Error:Field validation for "" failed on the "email" tag return } // email ok, move on } |
九、map to structure
-
golang map to structure 的库
GitHub地址:https://github.com/mitchellh/mapstructure
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | package main import ( "encoding/json" "fmt" "github.com/mitchellh/mapstructure" ) type Demo struct { ID int `json: "id" ` Name string `json: "name" ` } func main() { var value = make( map [string]Demo) value[ "1" ] = Demo{ ID: 1, Name: "name-1" , } valueData, err := json.Marshal(value) if err != nil { panic(err) } var newValue interface {} if err = json.Unmarshal(valueData, &newValue); err != nil { panic(err) } // 反序列化之后只能强转为map[string]interface{} for _, v := range newValue.( map [string] interface {}) { /* 此时可以使用mapstructure.Decode方法编码,该方法使用的是反射的机制; 也可以对v进行序列化,然后反序列化给demo变量; */ var demo Demo if err = mapstructure.Decode(v, &demo); err != nil { panic(err) } fmt.Println(demo) } } |
- 作者:踏雪无痕
- 出处:http://www.cnblogs.com/chenpingzhao/
- 本文版权归作者和博客园共有,如需转载,请联系 pingzhao1990#163.com
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!