3. 基于 flag 包实现命令行参数解析工具

基于 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。

命令行输入 profile -name Alice -port 8080 flag.Parse() 解析并校验参数 成功 失败 获取参数值 *name, *port, *debug, *host 错误处理 打印错误信息 → os.Exit(2) 参数注册与类型映射 flag.String -name "Alice" 默认值: "guest" flag.Int -port 8080 默认值: 80 flag.Bool -debug 默认值: false flag.String -host "localhost" 默认值: "127.0.0.1" 每个 flag 函数返回对应类型的指针,解析后通过 *ptr 读取值 非法输入(如 -port abc)由 flag 包自动捕获并报错 -h / --help 触发 Usage 输出,展示所有参数及默认值

完整实现代码

以下代码可直接保存为 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。