golang基于结构体生成多类型命令行标志的插件库sflags的使用
Golang基于结构体生成多类型命令行标志的插件库sflags的使用
sflags是一个使用结构体、反射和结构体字段标签来定义命令行选项的Golang库。它支持多种类型和特性。
基本使用示例
下面是一个使用sflags的基本示例:
package main
import (
"flag"
"log"
"time"
"github.com/urfave/sflags/gen/gflag"
)
// HTTP配置结构体
type httpConfig struct {
Host string `desc:"HTTP host"` // 描述信息
Port int // 端口号
SSL bool // 是否启用SSL
Timeout time.Duration // 超时时间
}
// 主配置结构体
type config struct {
HTTP httpConfig // HTTP配置
}
func main() {
// 初始化配置默认值
cfg := &config{
HTTP: httpConfig{
Host: "127.0.0.1",
Port: 6000,
SSL: false,
Timeout: 15 * time.Second,
},
}
// 将结构体转换为命令行标志
err := gflag.ParseToDef(cfg)
if err != nil {
log.Fatalf("err: %v", err)
}
// 解析命令行参数
flag.Parse()
}
运行上面的代码会生成以下输出:
$ go run ./main.go --help
Usage of _obj/exe/main:
-http-host value
HTTP host (default 127.0.0.1)
-http-port value
(default 6000)
-http-ssl
-http-timeout value
(default 15s)
exit status 2
支持的标志库和特性
sflags支持多种流行的命令行标志库:
库 | 隐藏 | 废弃 | 短名 | 环境变量 | 必填 |
---|---|---|---|---|---|
flag | - | - | - | - | - |
kingpin | ✓ | - | ✓ | ✓ | ✓ |
spf13/pflag | ✓ | ✓ | ✓ | - | - |
spf13/cobra | ✓ | ✓ | ✓ | - | - |
urfave/cli | ✓ | - | ✓ | ✓ | ✓ |
主要特性
- 设置环境变量名
- 设置使用说明
- 支持长格式和短格式标志
- 跳过字段
- 必填字段
- 废弃和隐藏选项
- 多个环境变量名
- 用户自定义类型接口
- 验证功能(使用govalidator包)
- 匿名嵌套结构支持
支持的结构体类型
- 各种整数类型(int, int8, int16, int32, int64)
- 各种无符号整数类型(uint, uint8, uint16, uint32, uint64)
- 浮点类型(float32, float64)
- 上述数字类型的切片(如[]int, []float64)
- 布尔类型(bool)
- 布尔切片([]bool)
- 字符串(string)
- 字符串切片([]string)
- 嵌套结构体
- net.TCPAddr
- net.IP
- time.Duration
- regexp.Regexp
- 上述类型的映射(如map[int64]bool, map[string]float64)
标志标签选项
标志默认键名是结构体字段名,但可以在结构体字段的标签值中指定。"flag"键在结构体字段的标签值中是键名,后跟可选的逗号和选项。例如:
// 忽略此字段
Field int `flag:"-"`
// 标志显示为"myName"
Field int `flag:"myName"`
// 如果此字段来自嵌套结构体,则忽略父结构体的前缀
Field int `flag:"~myName"`
// 通过空格后的值设置短名称
// 前缀不会应用于短名称
Field int `flag:"myName a"`
// 此字段将从生成的帮助文本中移除
Field int `flag:",hidden"`
// 此字段将在生成的帮助文本中标记为已废弃
Field int `flag:",deprecated"`
描述标签选项
如果在描述标签(默认为"desc")中指定描述,它将用于USAGE部分。
Addr string `desc:"HTTP host"`
解析函数选项
// DescTag 设置自定义描述标签,默认为"desc"
func DescTag(val string)
// FlagTag 设置自定义标志标签,默认为"flag"
func FlagTag(val string)
// Prefix 设置将应用于所有标志的前缀(如果它们没有标记为~)
func Prefix(val string)
// EnvPrefix 设置将应用于所有环境变量的前缀(如果它们没有标记为~)
func EnvPrefix(val string)
// FlagDivider 设置标志的自定义分隔符,默认为破折号,例如"flag-name"
func FlagDivider(val string)
// EnvDivider 设置环境变量的自定义分隔符
// 默认为下划线,例如"ENV_NAME"
func EnvDivider(val string)
// Validator 设置标志的验证函数
// 检查sflags/validator包中存在的验证器
func Validator(val ValidateFunc)
// 如果不想匿名结构字段被扁平化,设置为false
func Flatten(val bool)
已知问题
- kingpin不传递布尔参数的值。计数器无法从参数中获取初始值。
类似项目
更多关于golang基于结构体生成多类型命令行标志的插件库sflags的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang基于结构体生成多类型命令行标志的插件库sflags的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用sflags库基于结构体生成多类型命令行标志
sflags是一个强大的Go库,它允许你通过结构体定义自动生成命令行标志(flags),支持多种数据类型和自定义验证。下面我将详细介绍如何使用sflags。
基本用法
首先安装sflags库:
go get github.com/qwenode/sflags
简单示例
package main
import (
"fmt"
"log"
"os"
"github.com/qwenode/sflags"
"github.com/qwenode/sflags/gen/gpflag"
)
type Config struct {
Host string `desc:"Server host" default:"localhost"`
Port int `desc:"Server port" default:"8080"`
Debug bool `desc:"Enable debug mode"`
Timeout int `desc:"Request timeout in seconds" default:"30"`
MaxRetry int `desc:"Maximum retry attempts" default:"3"`
}
func main() {
cfg := &Config{}
// 将结构体转换为flag集
pflagSet, err := gpflag.Parse(cfg)
if err != nil {
log.Fatalf("failed to parse flags: %v", err)
}
// 解析命令行参数
pflagSet.Parse(os.Args[1:])
fmt.Printf("Config: %+v\n", cfg)
}
运行程序时可以使用标准的flag语法:
./app --host=example.com --port=9000 --debug --timeout=60
高级特性
1. 嵌套结构体
type DatabaseConfig struct {
URL string `desc:"Database connection URL" default:"postgres://localhost:5432"`
PoolSize int `desc:"Connection pool size" default:"10"`
}
type AppConfig struct {
Server struct {
Host string `desc:"Server host" default:"0.0.0.0"`
Port int `desc:"Server port" default:"8080"`
}
DB DatabaseConfig
}
生成的flag会像这样:
--server.host
--server.port
--db.url
--db.pool-size
2. 切片类型支持
type Config struct {
AllowedIPs []string `desc:"List of allowed IP addresses"`
Ports []int `desc:"List of ports to listen on" default:"80,443"`
}
使用方式:
./app --allowed-ips=192.168.1.1,10.0.0.1 --ports=8080,8081
3. 自定义验证
type Config struct {
Port int `desc:"Server port" validate:"min=1024,max=65535"`
}
func main() {
cfg := &Config{}
// 添加验证器
validator := sflags.NewValidator()
validator.RegisterFunc("min", func(v interface{}, param string) error {
// 实现最小值验证
return nil
})
_, err := gpflag.Parse(cfg, gpflag.WithValidator(validator))
// ...
}
4. 环境变量支持
type Config struct {
APIKey string `desc:"API key" env:"API_KEY"`
}
sflags会自动从环境变量中读取值。
完整示例
package main
import (
"fmt"
"log"
"os"
"github.com/qwenode/sflags"
"github.com/qwenode/sflags/gen/gpflag"
)
type ServerConfig struct {
Host string `desc:"Server host" default:"0.0.0.0"`
Port int `desc:"Server port" default:"8080"`
Enabled bool `desc:"Enable server"`
AllowedCORS []string `desc:"Allowed CORS origins" default:"*"`
}
type DatabaseConfig struct {
URL string `desc:"Database URL" env:"DB_URL"`
Username string `desc:"Database username"`
Password string `desc:"Database password"`
PoolSize int `desc:"Connection pool size" default:"10"`
}
type Config struct {
Server ServerConfig
Database DatabaseConfig
Debug bool `desc:"Enable debug mode"`
}
func main() {
cfg := &Config{}
// 生成flag集
pflagSet, err := gpflag.Parse(cfg,
gpflag.WithEnvPrefix("APP_"), // 环境变量前缀
)
if err != nil {
log.Fatalf("Failed to generate flags: %v", err)
}
// 解析命令行参数
pflagSet.Parse(os.Args[1:])
// 打印配置
fmt.Printf("Configuration:\n%+v\n", cfg)
// 使用帮助标志
if help, _ := pflagSet.GetBool("help"); help {
pflagSet.PrintDefaults()
os.Exit(0)
}
}
优势总结
- 声明式配置:通过结构体定义配置,代码更清晰
- 类型安全:自动处理类型转换
- 灵活扩展:支持嵌套结构体、切片、自定义类型
- 多来源:支持命令行参数、环境变量、默认值
- 验证支持:内置验证功能
sflags是一个强大的工具,可以显著简化Go应用程序的配置管理,特别是对于需要复杂配置结构的项目。