一个增强版的 Go 命令行参数解析库,兼容标准库 flag 的用法,并在此基础上扩展了配置文件、环境变量、隐藏参数、子命令、别名、字符串/数值切片等能力。
- 多来源优先级:命令行参数 > 环境变量 > 配置文件 > 默认值
- 🌟 统一配置入口
-c:Parse()自动注册隐藏参数-c,传入配置文件后命令行/环境变量/配置文件按优先级一次性合并,无需手动调用 viper - 配置文件集成:基于 viper,支持 JSON / TOML / YAML 等格式,参数变更可回写配置
- 隐藏参数:支持注册不在
--help中显示的参数,但仍可被解析 - 子命令 & 别名:支持注册子命令(如
git风格),并为参数/子命令设置别名(如-v↔--verbose) - 切片类型:内置
Strings / Ints / Int64s / Uints / Uint64s等切片类型,逗号分隔解析、多次传参自动累加 - 反射通用入口
Var():一个 API 覆盖所有基础类型和切片类型 - 彩色帮助输出:内置 ANSI 彩色打印,
PrintAll以表格形式列出全部参数
go get github.com/lfhy/flagpackage main
import (
"fmt"
"github.com/lfhy/flag"
)
var (
Port int
Host string
Tags []string
Debug bool
)
func init() {
flag.IntVar(&Port, "port", 8080, "服务端口")
flag.StringVar(&Host, "host", "127.0.0.1", "监听地址")
flag.StringsVar(&Tags, "tags", "go,linux", "标签(逗号分隔)")
flag.BoolVar(&Debug, "debug", false, "调试模式")
flag.Parse()
}
func main() {
fmt.Printf("Port=%d Host=%s Tags=%v Debug=%v\n", Port, Host, Tags, Debug)
}运行:
$ go run main.go -port 9000 -tags a,b -tags c
Port=9000 Host=127.0.0.1 Tags=[a b c] Debug=false包级别提供了与标准库一致风格的 XxxVar / Xxx 函数;也可通过 FlagSet 在子命令中独立使用。
| 方式 | 说明 |
|---|---|
flag.IntVar(p, "n", 1, "...") |
基础类型,仅命令行 + 默认值 |
flag.IntEnvVar(p, "n", "APP_N", 1, "...") |
同时绑定环境变量 |
flag.IntConfigVar(p, "n", "server", "port", 1, "...") |
同时绑定配置文件 |
flag.IntFullVar(p, "n", "server", "port", "APP_N", 1, "...") |
全部来源 |
flag.Int("n", 1, "...") |
返回 *int,无需预先定义变量 |
函数名加 Hidden(如 IntHiddenVar) |
注册为隐藏参数 |
所有类型(Bool / String / Int / Int64 / Uint / Uint64 / Float64 / Duration 以及对应的切片 Strings/Ints/... )均遵循同一套命名规则。
切片类型支持逗号分隔解析,多次传参会累加(与 pflag 的 StringSlice 行为一致):
var ids []int
flag.IntsVar(&ids, "ids", "1,2,3", "ID 列表")
// -ids=4,5 -ids=6 → [1 2 3 4 5 6]支持:StringsVar / IntsVar / Int64sVar / UintsVar / Uint64sVar。
Var() 接收一个 FlagVar 结构体,通过反射自动识别基础类型和切片类型,无需为每种类型单独调用 API:
var (
name string
age int
tags []string
ids []int64
)
flag.Var(&flag.FlagVar{Value: &name, Name: "name", Env: "APP_NAME", DefaultValue: "default"})
flag.Var(&flag.FlagVar{Value: &age, Name: "age", DefaultValue: 18})
flag.Var(&flag.FlagVar{Value: &tags, Name: "tags", DefaultValue: "a,b,c"})
flag.Var(&flag.FlagVar{Value: &ids, Name: "ids", DefaultValue: []int64{1, 2}})Var() 支持的类型:bool / string / int* / uint* / float64 / time.Duration 以及对应的切片。
// 绑定环境变量:未在命令行指定时从环境变量读取
flag.StringEnvVar(&host, "host", "APP_HOST", "0.0.0.0", "监听地址")
// 绑定配置文件:从 title.key 读取
flag.IntConfigVar(&port, "port", "server", "port", 8080, "服务端口")
// 读取/回写配置
cfg := flag.GetConfig()
cfg.WriteToConfig("server", "port", 9000)优先级:命令行 > 环境变量 > 配置文件 > 默认值。
这是本库区别于标准库 flag 的核心特性。Parse() 时会自动注册一个隐藏参数 -c,传入配置文件路径后,命令行参数、配置文件、环境变量会在一次解析中按优先级统一合并,无需手动调用 viper。
// app.go
var (
Host string
Port int
)
func init() {
flag.StringVar(&Host, "host", "127.0.0.1", "监听地址")
flag.IntConfigVar(&Port, "port", "server", "port", 8080, "服务端口")
flag.Parse()
}假设有配置文件 config.toml:
[server]
port = 9000三种来源合并:
# 1. 完全使用配置文件
$ go run app.go -c config.toml
# Host=127.0.0.1(默认值) Port=9000(来自配置文件)
# 2. 命令行覆盖配置文件
$ go run app.go -c config.toml -port 8888
# Port=8888(命令行 > 配置文件)
# 3. 环境变量也参与(未在命令行/配置中出现时生效)
$ APP_HOST=0.0.0.0 go run app.go -c config.toml
# Host=0.0.0.0(环境变量 > 默认值)要点:
-c是自动注册的隐藏参数,无需手动定义;未指定时跳过文件解析- 可通过
fs.SetConfigFlagName("conf")自定义参数名(FlagSet 级别,互不影响,默认"c") - 配置文件按
ConfigTitle.ConfigKey(即IntConfigVar第二、三个参数)的节/键读取 - 可通过
flag.DefaultConfigFlagName修改默认标志名(默认"c") - 解析完成后用
flag.GetConfig()获取*Config,支持读写回文件
flag.String("verbose", "false", "详细输出")
flag.Alias("verbose", "v") // -v 等价于 --verboseflag.StringHiddenVar(&token, "token", "", "内部鉴权 Token")
// 不会出现在 --help 输出中,但 -token=xxx 仍然生效实现 Cmd 接口(Name / Init / Run / Help)后注册即可:
type ServeCmd struct { *flag.FlagSet }
func (*ServeCmd) Name() string { return "serve" }
func (s *ServeCmd) Init(args ...string) error {
s.FlagSet = flag.NewFlagSet("serve", flag.ContinueOnError)
// ... 定义子命令参数
return s.Parse(args)
}
func (*ServeCmd) Run(args ...string) error { /* ... */ return nil }
func (*ServeCmd) Help() string { return "启动服务" }
flag.RegisterCommand(&ServeCmd{})
flag.Parse()每个类型在每个层级(FlagSet 方法 / ArgsFlag 方法 / 包级函数)都提供 8 个函数:
XxxFullVar / XxxConfigVar / XxxEnvVar / XxxVar // 写入已定义变量
XxxFull / XxxConfig / XxxEnv / Xxx // 返回 *T
加上对应 8 个 Hidden 变体。覆盖类型:
| 基础类型 | 切片类型 |
|---|---|
| Bool / String | Strings |
| Int / Int64 | Ints / Int64s |
| Uint / Uint64 | Uints / Uint64s |
| Float64 | — |
| Duration | — |
go test ./...MIT