已安装Go且版本≥1.19:运行go version确认;否则从官网下载最新版,避免brew安装;项目需go mod init初始化;flag解析须调用flag.Parse()并解引用;跨平台编译需显式设置GOOS/GOARCH,纯Go工具建议CGO_ENABLED=0。

确认系统是否已安装 Go 及版本是否合适
直接运行 go version,如果返回类似 go version go1.21.0 darwin/arm64 的结果,说明已安装且版本 ≥ 1.19(当前命令行工具开发推荐最低版本)。若提示 command not found: go 或版本低于 1.16,建议卸载旧版后从 https://www.php.cn/link/81836b7cd16991abb7febfd7832927fd 下载最新稳定版安装包——别用包管理器(如 brew install go)在 macOS 上装,它常默认装到 /opt/homebrew/bin/go,而 GOPATH 和模块初始化行为容易和系统路径冲突。
初始化项目并启用 Go Modules
进到你打算放代码的目录(比如 ~/projects/hello-cli),执行:
go mod init hello-cli。这会生成
go.mod 文件。注意:不要在 $GOPATH/src 下操作,Go 1.16+ 默认关闭 GOPATH 模式,硬塞进去反而导致 go run 找不到依赖或误判为 legacy 模式。如果看到错误 cannot find module providing package ...,大概率是当前目录没 go.mod,或者你在子目录里执行了 go run main.go 却忘了先 go mod init。
写一个带 flag 解析的最小可用 CLI
新建 main.go,内容不必套模板,从最简结构开始:
package main
import (
"flag"
"fmt"
"os"
)
func main() {
name := flag.String("name", "World", "name to greet")
flag.Parse()
if len(flag.Args()) > 0 {
fmt.Printf("Hi %s!\n", flag.Args()[0])
} else {
fmt.Printf("Hello, %s!\n", *name)
}
}关键点:flag.String 返回的是 *string,必须解引用(*name);flag.Parse() 必须在所有 flag 声明之后、业务逻辑之前调用;flag.Args() 拿的是非 flag 参数(比如 ./hello-cli Alice 中的 Alice),和 -name=Bob 是两套输入路径。漏掉 flag.Parse() 会导致所有 flag 值保持默认,且 flag.Args() 为空。
编译与跨平台分发时要注意 CGO 和目标 OS
本地测试用 go run main.go 最快,但发布前得编译:
GOOS=linux GOARCH=amd64 go build -o hello-cli-linux main.go。Windows 用户若想生成 Linux 二进制,必须显式设
GOOS 和 GOARCH——Go 默认按宿主系统编译。若代码里用了 os/user 或 net/http 等标准库,通常没问题;但一旦引入 C 依赖(比如 SQLite 或某些图像库),CGO_ENABLED=0 就可能失败,此时得保留 CGO_ENABLED=1 并配好对应平台的交叉编译工具链。大多数纯 Go CLI 工具,关掉 CGO 更干净:CGO_ENABLED=0 GOOS=darwin go build -a -o hello-cli-darwin main.go
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
实际交付时,别只扔一个二进制文件出去——至少附上 README.md 说明怎么传参、支持哪些 flag,否则用户运行 ./hello-cli --help 看不到任何输出,因为没调用 flag.Usage 或注册自定义 help 逻辑。
立即学习“go语言免费学习笔记(深入)”;

















