Go 用 flag 包解析命令行参数最直接:flag.Float64/flag.String 自动类型转换与校验,须在 flag.Parse() 前定义所有 flag;不支持位置参数;四则运算用 switch 清晰易扩展,需显式检查除零;输出用 %.2f 统一精度,错误输出到 os.Stderr 且以 error: 开头;编译后单文件静态分发,Windows 需加 .exe 后缀。
flag 解析命令行参数最直接Go 自带的 flag 包足够应付简单计算器的输入需求,比如 calc -op add -a 3.5 -b 2.1。不用引入第三方库,也避免了手动解析 os.Args 容易出错的问题(比如空值、类型转换失败未处理)。
关键点:
flag.Float64 和 flag.String 会自动做类型转换和基础校验,失败时默认打印用法并退出flag.Parse() 之前定义所有 flag,否则会被忽略calc add 3 5),就得放弃 flag 改用 os.Args[1:] 手动处理——但会失去自动帮助提示和类型安全switch 最清晰把操作符映射到具体函数,switch 比一堆 if/else if 更易读、更易扩展。注意除零要显式检查,浮点数除零在 Go 中不会 panic,但会得到 +Inf 或 -Inf,这不是用户想要的结果。
switch op {
case "add":
result = a + b
case "sub":
result = a - b
case "mul":
result = a * b
case "div":
if b == 0 {
fmt.Fprintln(os.Stderr, "e
rror: division by zero")
os.Exit(1)
}
result = a / b
default:
fmt.Fprintf(os.Stderr, "error: unsupported operator %q\n", op)
os.Exit(1)
}fmt.Printf 控制精度用户输入可能是整数也可能是小数,但输出全保留小数点后两位(或按需截断)更友好。用 %.2f 而不是 %f,避免出现 5.000000 这类冗余显示。
另外,错误信息必须输出到 os.Stderr,正常结果输出到 os.Stdout,否则管道使用(如 calc -op add -a 1 -b 2 | grep 3)会混乱。
error: 开头,便于 grep 过滤log.Fatal,它会额外打时间戳,破坏 CLI 工具的简洁性Go 的静态链接特性意味着编译出的单文件不含外部依赖。执行 go build -o calc main.go 后,生成的 calc 可直接拷给没装 Go 的机器运行。
几个容易被忽略的细节:
.exe 后缀,否则用户运行 calc 会报“不是内部或外部命令”chcp 65001)-a abc),因为 flag.Float64 已在解析阶段报错,无需重复检查