3. 基于 flag 包实现命令行参数解析工具
任务目标与参数设计
本案例实现一个名为 profile 的命令行工具,用于生成一份用户配置摘要。程序需要解析四类参数:字符串(用户名)、整数(端口)、布尔(是否开启调试)、以及带默认值的参数(主机地址)。当用户输入非法值(如端口写成 abc 或超出 1–65535 范围)时,程序应给出明确错误提示并退出;当用户传入 -h 或 --help 时,输出结构化的帮助信息。
flag 包的核心机制
Go 标准库 flag 包通过 flag.String、flag.Int、flag.Bool 等函数注册参数,返回对应类型的指针。注册时需提供参数名、默认值和帮助说明。解析由 flag.Parse() 触发,解析失败时默认会打印错误并调用 os.Exit(2)。若希望自定义错误处理,可设置 flag.CommandLine.SetOutput 或使用 flag.NewFlagSet。
完整实现代码
以下代码可直接保存为 main.go,在模块中运行 go run main.go -name Alice -port 8080 -debug 即可看到输出。
package main
import (
"flag"
"fmt"
"os"
)
func main() {
// 注册参数:名称、默认值、帮助说明
name := flag.String("name", "guest", "用户名(字符串)")
port := flag.Int("port", 80, "监听端口(1-65535)")
debug := flag.Bool("debug", false, "是否开启调试模式")
host := flag.String("host", "127.0.0.1", "主机地址(默认值参数)")
// 自定义 Usage 输出,结构化展示所有参数
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "profile - 用户配置摘要工具\n\n")
fmt.Fprintf(os.Stderr, "用法: profile [选项]\n\n")
fmt.Fprintf(os.Stderr, "选项:\n")
flag.PrintDefaults()
fmt.Fprintf(os.Stderr, "\n示例:\n")
fmt.Fprintf(os.Stderr, " profile -name Alice -port 8080 -debug\n")
}
flag.Parse()
// 手动校验端口范围
if *port < 1 || *port > 65535 {
fmt.Fprintf(os.Stderr, "错误: 端口 %d 超出有效范围 1-65535\n", *port)
os.Exit(1)
}
// 输出结构化配置摘要
fmt.Println("=== 用户配置摘要 ===")
fmt.Printf("用户名 : %s\n", *name)
fmt.Printf("主机地址 : %s\n", *host)
fmt.Printf("端口 : %d\n", *port)
fmt.Printf("调试模式 : %v\n", *debug)
}
运行与验证
正常调用:
$ go run main.go -name Alice -port 8080 -debug
=== 用户配置摘要 ===
用户名 : Alice
主机地址 : 127.0.0.1
端口 : 8080
调试模式 : true
非法端口(超出范围):
$ go run main.go -port 99999
错误: 端口 99999 超出有效范围 1-65535
非法类型(flag 包自动捕获):
$ go run main.go -port abc
invalid value "abc" for flag -port: parse error
Usage of profile:
-debug
是否开启调试模式
-host string
主机地址(默认值参数) (default "127.0.0.1")
-name string
用户名(字符串) (default "guest")
-port int
监听端口(1-65535) (default 80)
查看帮助:
$ go run main.go -h
profile - 用户配置摘要工具
用法: profile [选项]
选项:
-debug
是否开启调试模式
-host string
主机地址(默认值参数) (default "127.0.0.1")
-name string
用户名(字符串) (default "guest")
-port int
监听端口(1-65535) (default 80)
示例:
profile -name Alice -port 8080 -debug
关键点:flag 包在解析失败时默认调用
os.Exit(2),因此非法类型(如 -port abc)不会进入主逻辑。而端口范围校验属于业务规则,需在 flag.Parse() 之后手动完成,并自行决定退出码(此处用 1)。
注意:布尔参数
-debug 不需要跟值,写 -debug 即为 true;若写成 -debug=false 也可显式关闭。字符串和整数参数必须用空格或等号连接值,如 -name=Alice 或 -name Alice。