用flag而非cobra因小工具无需子命令、自动help或补全,flag更轻量可控;三行即可解析参数,而cobra需建cmd目录、注册命令,易在路径或flag冲突上出错。

为什么用 flag 而不是 cobra?
小工具没到需要子命令、自动 help 生成、bash 补全的程度时,flag 更轻、更可控。你写三行就能拿到参数,cobra 却要建 cmd 目录、注册、绑定,反而容易在路径解析或 flag 冲突上卡住。
常见错误是把输入文件路径当字符串硬编码进 flag.String 默认值里,结果运行时没传参就 panic;或者用 flag.Parse() 后直接读 os.Args[1:],导致 flag 和非 flag 参数混在一起。
- 只用
flag.String/flag.Bool声明参数,不设默认值(除非是安全的空值,比如"") - 调用
flag.Parse()后,立刻检查flag.NArg() == 0,提示 “missing input file” - 输入路径用
flag.Arg(0)拿,别碰os.Args
io.Copy 转换文本格式够用吗?
够用,但仅限无状态、流式转换,比如 dos2unix 或大小写批量替换。一旦涉及 JSON 格式校验、XML 层级缩进、CSV 字段映射,就得切到结构化解析——这时候 io.Copy 只能做管道搬运工,真正干活得靠 json.Decoder 或 encoding/csv。
容易踩的坑是:用 io.Copy 处理大文件时没设 buffer,吞吐掉一半;或把 UTF-8 BOM 当普通字节扔掉,导致输出文件被某些编辑器识别为 ANSI。
- 用
bufio.NewReaderSize(in, 64*1024)包一层再传给io.Copy,避免默认 32KB 缓冲拖慢大文件 - 读取前先用
bytes.HasPrefix检查 BOM,需要保留就原样写入,不需要就跳过前 3 字节 - 别用
strings.ReplaceAll处理整文件内容——内存爆炸风险高,尤其 >100MB 文件
如何让错误信息指向真实问题位置?
Golang 默认错误只说 “invalid character”,对用户毫无意义。必须把原始文件名、行号、甚至出错字段名打进去,否则用户根本没法 debug。
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
典型场景:JSON 转 YAML 时,输入 JSON 有语法错误,但程序只报 invalid character '}' after top-level value,用户得自己开编辑器一行行查。
- 用
json.SyntaxError.Offset算出行号:bytes.Count(data[:offset], []byte{'\n'}) + 1 - 所有
fmt.Errorf都带上%w包裹底层 error,别用+ " failed"这种丢上下文写法 - 输出错误时加前缀
ERROR:,并确保 stderr 输出(log.New(os.Stderr, "", 0))
Windows 下路径和换行符怎么不翻车?
不是所有用户都用 Linux。Windows 用户传 C:\data\in.json,你的程序如果用 / 拼接输出路径,会生成 C:\data\out.yaml → C:\data\out.yaml 这种无效路径;或者把 \r\n 当成乱码过滤掉,导致 CSV 表格错行。
关键不是“适配 Windows”,而是别假设路径分隔符或换行符形态。
- 路径拼接一律用
filepath.Join("out", name),别用"out/" + name - 写文件时用
os.O_CREATE | os.O_WRONLY | os.O_TRUNC,别漏os.O_TRUNC,否则旧文件残留内容 - 换行统一用
\n输出,Windows 系统自带记事本会认,VS Code / Notepad++ 更没问题;非要兼容老旧软件才考虑\r\n
最麻烦的其实是用户把相对路径写成 ./input.json 却在别的目录执行命令——这得靠 filepath.Abs 转成绝对路径再处理,不然 open 会失败,还报错 “no such file or directory” 而不是具体哪个路径不对。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










