rand.intn每次结果相同是因为未初始化随机种子,需调用rand.seed(time.now().unixnano())或go 1.20+推荐的rand.new(rand.newsource(time.now().unixnano()))。

Go 里 rand.Intn 为啥每次运行都猜同一个数?
因为没初始化随机种子,rand 默认用固定种子,导致每次启动程序都生成相同序列。
- 必须在程序开头调用
rand.Seed(time.Now().UnixNano())(Go 1.20+ 推荐用rand.New(rand.NewSource(time.Now().UnixNano()))) - 如果用的是
math/rand包的全局函数(如rand.Intn),只调一次Seed就够了;但多 goroutine 并发时建议用独立的*rand.Rand实例 - 别在循环里反复调
Seed—— 时间戳可能重复,反而让随机性变差
用 fmt.Scanln 读用户输入时卡住或跳过?
常见于连续输入场景:前一次输入残留的换行符被下一次 Scanln 当作“空输入”直接返回。
- 优先用
fmt.Scan(忽略空白符)或bufio.NewReader(os.Stdin).ReadString('\n')精确读一行 -
Scanln要求输入末尾必须是换行,且会吃掉换行符;但若用户输完直接按回车,它没问题;若输完没按回车就程序继续,就会阻塞 - 读数字前先清空输入缓冲区:用
bufio.NewReader(os.Stdin).Discard(1024)不可靠,不如统一用ReadString+strconv.Atoi
怎么安全把字符串转成整数并处理错误?
strconv.Atoi 是最直接的方式,但它不处理空输入、空格、非数字字符等边界情况。
- 先用
strings.TrimSpace去首尾空格,再传给strconv.Atoi - 必须检查返回的
error:比如用户输"abc"或空行,err != nil,此时不能用默认值硬代入逻辑 - 别用
fmt.Sscanf替代 —— 它对格式要求更严,失败时不报具体原因,调试困难 - 示例:
input, _ := reader.ReadString('\n') num, err := strconv.Atoi(strings.TrimSpace(input)) if err != nil { fmt.Println("请输入有效数字") continue }
Windows 下编译的二进制运行时报错 stdin: is not a tty?
这通常不是 Go 代码问题,而是终端环境异常,尤其发生在通过某些 IDE 或远程 shell 启动时。
立即学习“go语言免费学习笔记(深入)”;
- 确认运行环境有标准输入流:在 CMD 或 PowerShell 中直接双击 exe 会失败,必须从终端中执行
- VS Code 的终端默认可用,但“运行”按钮(Ctrl+F5)可能绕过终端,改用“终端 → 运行任务 → go run”更稳
- 无需加任何 flag 或依赖库修复 —— Go 本身不依赖 TTY,只要
os.Stdin可读就行;报错说明上层环境没提供它











