You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从Go 1.13迁移至1.20.1时,如何改写rand.Seed(1)?

问题解决:Go 1.20+ 替换 rand.Seed(1) 的正确方式

在Go 1.13到1.20.1的迁移中,直接将rand.Seed(1)替换为rand.NewSource(1)会测试失败,核心原因是:rand.NewSource(1)仅创建了固定种子的随机源,但并未绑定到实际使用的随机生成器,全局rand包的函数依然使用默认种子生成随机序列,导致测试数据和预期不一致。

正确改写方案

需要创建一个本地的rand.Rand实例,基于固定种子的源生成随机数,确保所有随机调用都使用这个实例,而非全局rand函数:

修改bench_test.go中的makeData和makeWord函数如下:

func makeData() {
    file, err := os.Create("testdata/data.txt")
    if err != nil {
        panic(err)
    }
    defer file.Close()

    // 创建固定种子的随机源和对应的Rand实例
    rng := rand.New(rand.NewSource(1))
    for i := 0; i < 10000; i++ {
        // 使用本地rng实例生成随机数
        data := makeWord(rng, rng.Intn(10)+1)
        file.Write(data)
    }
}

// 修改makeWord函数,接收Rand实例作为参数
func makeWord(rng *rand.Rand, l int) []byte {
    out := make([]byte, l+1)
    for i := 0; i < l; i++ {
        // 使用本地rng实例生成随机数
        out[i] = 'a' + byte(rng.Intn(26))
    }
    out[l] = '\n'
    return out
}

改写说明

  1. 创建本地Rand实例:rand.New(rand.NewSource(1))生成一个基于固定种子的独立随机生成器,既避免全局rand的并发问题,也保证每次运行的随机序列完全一致。
  2. 传递Rand实例:将makeWord函数修改为接收*rand.Rand参数,确保所有随机数生成都使用这个固定实例,和原rand.Seed(1)的全局随机序列完全匹配。
  3. 保持测试一致性:修改后生成的testdata/data.txt大小仍为65204字节,TestFileLen测试可以顺利通过。

直接替换失败的原因

  • Go 1.20中rand.Seed已被废弃,它的作用是设置全局rand的默认源种子;
  • 仅调用rand.NewSource(1)不会改变全局rand的源,全局rand依然使用默认种子生成随机数,导致测试数据和预期不符,测试失败。

内容的提问来源于stack exchange,提问作者Đỗ Như Vỹ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 03:53:09