最直接绑定字符串变量的方式是 flag.StringVar(&name, "name", "default", "user name"),需传地址、在 flag.Parse() 前注册,否则变量为空;flag.String 返回新指针,不适用于已有变量。

用 flag.StringVar 直接绑定字符串变量
最直接的方式是调用 flag.StringVar,它会把命令行参数值写入你传入的字符串指针。注意:必须传地址,不是值;且需在 flag.Parse() 之前注册。
常见错误是传 &myVar 但 myVar 还没声明,或漏掉 flag.Parse() 导致变量始终为空。
-
flag.StringVar(&name, "name", "default", "user name")—— 第一个参数是*string,第二个是 flag 名(如-name),第三个是默认值,第四个是帮助说明 - 如果命令行传
-name=alice或-name alice,name变量就会被赋值为"alice" - 未提供该 flag 时,变量取默认值
"default",不是空字符串(除非你显式设为"")
为什么不能用 flag.String?
flag.String 返回的是 *string 类型的新变量地址,不是你已有的变量。它适合“不需要复用已有变量”的场景,比如临时解析、只读使用。
典型误用:name := flag.String("name", "def", "") → 此时 name 是个新指针,和你的局部 string 变量无关;想赋值给已有变量还得手动解引用:myName = *name,多此一举且易忘。
立即学习“go语言免费学习笔记(深入)”;
-
flag.String的返回值本质是内部新建的string,生命周期由flag包管理 - 如果你已有变量
var name string,就该用flag.StringVar(&name, ...),避免冗余分配 - 性能上无差异,但语义清晰、少出错
解析后必须调用 flag.Parse()
所有 flag.XxxVar 或 flag.Xxx 调用只是注册,真正读取命令行参数并赋值发生在 flag.Parse() 执行时。不调用它,你的变量永远保持初始值。
容易踩的坑:把 flag.Parse() 放在 if 分支里、或放在 defer 中、或干脆忘了写——结果程序跑起来参数全没生效。
- 标准位置是
main()开头,在所有 flag 注册之后、业务逻辑之前 -
flag.Parse()会自动处理--help和未知 flag,无需额外判断 - 它会修改
os.Args,剥离已解析的 flag 部分,后续os.Args剩下的是非 flag 参数(即flag.Args())
支持短选项、长选项与等号语法的细节
Golang flag 包默认只支持长选项(--name),但可通过命名约定兼容短选项(-n):只要定义 flag 名为单字母,就能用短格式;等号语法(-name=value)和空格分隔(-name value)都支持。
注意:短选项必须是单字符;多个短选项不能合并(-abc 不等于 -a -b -c),除非你分别注册 a、b、c 三个 flag。
- 定义
flag.StringVar(&name, "name", "", "")→ 支持--name alice和--name=alice - 定义
flag.StringVar(&n, "n", "", "")→ 支持-n alice和-n=alice - 不支持
-name alice(无短横线的单短横写法),这是flag包的设计限制
flag.String 再解引用,有人直接用 StringVar,混用容易引发 nil dereference 或静默赋值失败。


















