math/rand默认种子为1导致每次运行随机数相同,需用time.Now().UnixNano()设种;生成[1,100]整数应写为1+r.Intn(100);并发下应避免全局函数,推荐局部*rand.Rand实例或sync.Pool复用。
为什么 math/rand 生成的随机数每次运行都一样?
因为默认种子(seed)固定为 1,rand.NewSource(1) 导致序列完全可复现。这不是 bug,是设计使然——方便测试,但生产环境必须手动设种。
正确做法是用当前时间纳秒级精度初始化:
src := rand.NewSource(time.Now().UnixNano()) r := rand.New(src)
注意别在循环里反复调用 time.Now() 初始化,否则高并发下可能撞上相同种子;全局复用一个 *rand.Rand 实例更安全。
如何生成指定范围的随机整数(比如 [1, 100])?
rand.Intn(n) 返回 [0, n) 的整数,不能直接套用。要得到闭区间 [min, max],得做偏移和长度校准:
- 先算长度:
max - min + 1 - 再加偏移:
min + r.Intn(max-min+1)
例如生成 1 到 100(含):
num := 1 + r.Intn(100) // ✅ 不是 r.Intn(100) + 1 写法错误,但语义等价;重点是范围计算别漏 +1
常见错误:写成 r.Intn(100) + 1 看似对,但如果 min 是变量,漏掉 +1 就变成 [min, max) 了。
如何生成随机浮点数或字符串?
math/rand 提供 Float32() 和 Float64(),返回 [0.0, 1.0) 区间值,缩放即可: