bufio.scanner卡住主因是未循环调用scan()或输入未结束(缺换行符/eof);readstring易受\r\n干扰,需trimspace;交互式场景按语义选scanner(逐行)或reader(灵活控制)。

bufio.Scanner 读取标准输入时卡住不返回?
绝大多数情况是没调用 Scan() 或没处理换行符导致阻塞。它默认按行读取,遇到 EOF 或换行才返回;如果用户只输了一半就切走、或终端没发回车,Scanner 就一直等。
- 必须在循环里调用
Scan(),不能只调一次就以为读完了 - 如果想读单个字符或非换行分隔的内容,别硬改
SplitFunc,直接换bufio.Reader - 注意:Windows 下 Ctrl+Z、Linux/macOS 下 Ctrl+D 才触发 EOF,不是 Enter
- 示例中常漏掉
err := scanner.Err()检查,导致 EOF 后的错误被忽略
为什么 bufio.NewReader(os.Stdin).ReadString('\n') 有时读不到完整输入?
因为 ReadString() 匹配的是第一个出现的 '\n',而用户粘贴内容可能含多行,或终端把 \r\n 当作两个字符处理——尤其在 Windows 上,ReadString('\n') 会把 \r 留在缓冲区,下次读就直接拿到空字符串。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 读完后务必用
strings.TrimSpace()去掉\r和首尾空白 - 不要用
ReadString('\r\n')—— Go 不支持多字符分隔符 - 若需兼容性更强,用
reader.ReadString('\n')+strings.TrimRight(s, "\r\n") - 性能上,
ReadString比Scanner略低,因每次都要扫描缓冲区找分隔符
Scanner 和 Reader 在交互式输入场景下怎么选?
看你要不要“一行一处理”这个语义。需要逐行解析命令(如 REPL)、且允许用户 Ctrl+D 退出,用 Scanner 更自然;要读密码、单字符响应、或者中间夹杂二进制数据,Reader 是唯一选择。
-
Scanner自动跳过空行、处理 UTF-8 边界,但无法读部分行 -
Reader可以Peek()、UnreadRune()、ReadByte(),适合协议解析类逻辑 - 两者都依赖底层
os.Stdin的缓冲行为,别混着用同一个os.Stdin实例 - 如果程序要同时读命令和文件内容,记得用
io.MultiReader或显式分离 reader
stdin 被重定向时 Scanner.Scan() 返回 false 却没报错?
这是正常行为:Scan() 在 EOF 时返回 false,但 scanner.Err() 是 nil。很多人误以为“没错误就是还有数据”,结果提前退出。
- 判断结束必须写成
for scanner.Scan() { ... },而不是if scanner.Scan() - EOF 不是错误,是流结束状态,所以
scanner.Err()只在真正出错(如解码失败)时非 nil - 重定向文件输入时,如果文件末尾缺换行符,
Scanner仍能正确读最后一行——这点比ReadString更鲁棒 - 调试时可用
fmt.Printf("text: %q err: %v\n", scanner.Text(), scanner.Err())快速确认状态
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










