Golang中rand.Intn函数总是返回"1"的原因分析

Golang中rand.Intn函数总是返回"1"的原因分析 有个小问题:为什么我的函数总是返回“1”?

fmt.Println(rand.Intn(10))

我读到过,如果你使用 Go Playground,可能会遇到这样的问题——但我在使用自己电脑的控制台时也出现了同样的情况。求助 slight_smile

7 回复
rand.Seed(time.Now().UnixNano())
fmt.Println(rand.Intn(10))

现在可以正常工作了,非常感谢!

更多关于Golang中rand.Intn函数总是返回"1"的原因分析的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


我正在使用 math/rand。我尝试过 crypto/rand,但它现在无法识别 “rand.Intn” 😄 crypto/rand 很可能有一个不同的函数,对吧?“Crypto/intn(10)” 也不行 😅

调用 time.Now(),然后在其上调用 UnixNano 方法以获取一个具有一定随机性的 int64 值。

调用 time.Now().UnixNano() 来获取一个 int64 值。

伪随机数就足够了,我只是需要检查我代码的其他部分是否正常工作。我是个完全的新手,没有完全理解您描述的步骤(😂)。我的意思是,我理解了生成伪随机数所需的“源”或“种子”的概念,以及为什么当前日期会是一个好的起点。我尝试了这样写:

rand.Seed(time.Now())
fmt.Println(rand.Intn(10))

但是我得到了这个错误:

cannot use time.Now() (value of type time.Time) as type int64 in argument to rand.Seed

根据我的理解,我需要将日期转换为一个数字来修复这个问题。 或者重新阅读您的回复并尝试弄清楚 😊

我来帮助你! 😄

你使用的是 math/rand 还是 crypto/rand?前者除非你为其源(Source)设置种子,否则总是会生成相同的伪随机数序列。根据文档

随机数由一个源(Source)生成。顶级函数,如 Float64 和 Int,使用一个默认的共享源,该源在每次程序运行时产生一个确定性的值序列。如果每次运行需要不同的行为,请使用 Seed 函数来初始化默认源。

func main() {
    fmt.Println("hello world")
}

这是因为你没有设置随机数种子。rand.Intn 默认使用一个确定性种子(通常是 1),导致每次运行都产生相同的序列。

解决方法: 在程序开始时调用 rand.Seed 函数,通常使用当前时间作为种子。

package main

import (
    "fmt"
    "math/rand"
    "time"
)

func main() {
    rand.Seed(time.Now().UnixNano()) // 设置随机数种子
    fmt.Println(rand.Intn(10)) // 现在会返回 0-9 之间的随机数
}

关键点:

  1. rand.Seed 只需要调用一次,通常在 main 函数开始处
  2. time.Now().UnixNano() 提供纳秒级时间戳,确保每次运行种子不同
  3. 从 Go 1.20 开始,推荐使用 rand.New(rand.NewSource(seed)) 创建独立的随机数生成器

Go 1.20+ 推荐写法:

func main() {
    r := rand.New(rand.NewSource(time.Now().UnixNano()))
    fmt.Println(r.Intn(10))
}

你打算如何处理这些随机生成的数字?它们是否需要是密码学安全的,还是伪随机数就足够了?如果 math/rand.Intn 对你来说足够好,而你只是希望数字不那么容易被预测,我建议:

  • 使用 math/rand.NewSource 创建一个新的 math/rand.Source。 一种获取伪随机种子传递给 rand.NewSource 的方法是使用当前时间(调用 time.Now,然后在其上调用 UnixNano 方法来获取一个具有一定随机性的 int64 值)。

  • 将该种子传递给 math/rand.New 以创建一个新的随机数生成器(例如,将其命名为 myRand)。

  • 现在,你可以使用你独立的 myRand 生成器,并在其上调用 Intn,而不是调用 math/rand.Intn

回到顶部