Golang中rand.Intn函数总是返回"1"的原因分析
Golang中rand.Intn函数总是返回"1"的原因分析 有个小问题:为什么我的函数总是返回“1”?
fmt.Println(rand.Intn(10))
我读到过,如果你使用 Go Playground,可能会遇到这样的问题——但我在使用自己电脑的控制台时也出现了同样的情况。求助 
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 之间的随机数
}
关键点:
rand.Seed只需要调用一次,通常在main函数开始处time.Now().UnixNano()提供纳秒级时间戳,确保每次运行种子不同- 从 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。

