英文:
Is it necessary to call rand.Seed manually?
问题
在Go语言中,如果你想要生成不同的随机数序列,你需要在调用rand.Intn(100)
之前调用rand.Seed(n)
来设置随机数种子。种子值n
可以是任意整数,通常使用当前时间的纳秒数作为种子值,例如rand.Seed(time.Now().UnixNano())
。这样做可以确保每次运行程序时都会生成不同的随机数序列。所以,在你的代码中,你需要在每次调用rand.Intn(100)
之前调用rand.Seed(n)
来确保每次运行时都会生成不同的随机数。
英文:
I want to know do we have to call rand.Seed(n)
manually in Go?
I have a code that looks like this:
import (
"fmt"
"math/rand"
)
func main() {
fmt.Println(rand.Intn(100))
fmt.Println(rand.Intn(100))
fmt.Println(rand.Intn(100))
}
Everytime I run this code, each line prints different numbers than the others.
So do I need to call rand.Seed(n)
each time before calling rand.Intn(100)
?
答案1
得分: 6
在 Go 1.20 之前,全局共享的随机数源在内部被初始化为 1,因此每次运行应用程序都会产生相同的伪随机序列。
从 Go 1.20 开始,不再需要调用 rand.Seed()
。发布说明:
> math/rand
包现在会自动使用随机值对全局随机数生成器(由 Float64
和 Int
等顶级函数使用)进行初始化,而顶级的 Seed
函数已被弃用。 需要可重现的随机数序列的程序应该优先分配自己的随机源,使用 rand.New(rand.NewSource(seed))
。
>
> 需要早期一致的全局初始化行为的程序可以在环境中设置 GODEBUG=randautoseed=0
。
>
> 顶级的 Read
函数已被弃用。在几乎所有情况下,更适合使用 crypto/rand.Read
。
rand.Seed()
的文档中也有这个弃用声明:
> 弃用:调用 Seed,然后期望从全局随机源(使用 Int 等函数)获得特定结果序列的程序,在依赖项更改其从全局随机源中消耗的量时可能会出现问题。为了避免这种问题,需要特定结果序列的程序应该使用 NewRand(NewSource(seed)) 来获取其他包无法访问的随机生成器。
英文:
Prior to Go 1.20, the global, shared Source was seeded to 1 internally, so each run of the appliation would produce the same pseudo-random sequences.
Calling rand.Seed()
is not needed starting from Go 1.20. Release notes:
> The math/rand
package now automatically seeds the global random number generator (used by top-level functions like Float64
and Int
) with a random value, and the top-level Seed
function has been deprecated. Programs that need a reproducible sequence of random numbers should prefer to allocate their own random source, using rand.New(rand.NewSource(seed))
.
>
> Programs that need the earlier consistent global seeding behavior can set GODEBUG=randautoseed=0
in their environment.
>
> The top-level Read
function has been deprecated. In almost all cases, crypto/rand.Read
is more appropriate.
rand.Seed()
also has this DEPRICATION in its doc:
> Deprecated: Programs that call Seed and then expect a specific sequence of results from the global random source (using functions such as Int) can be broken when a dependency changes how much it consumes from the global random source. To avoid such breakages, programs that need a specific result sequence should use NewRand(NewSource(seed)) to obtain a random generator that other packages cannot access.
答案2
得分: 1
你需要创建一个源代码:
package main
import (
"fmt"
"math/rand"
)
func main() {
wdRand := rand.New(rand.NewSource(42))
fmt.Println(wdRand.Intn(100))
fmt.Println(wdRand.Intn(100))
fmt.Println(wdRand.Intn(100))
}
现在每次调用这段代码,结果都会变得相同。
你可以在这个链接上运行代码并查看结果:https://go.dev/play/p/Sp0Wfx0Bkbb
英文:
You have to create a Source:
package main
import (
"fmt"
"math/rand"
)
func main() {
wdRand := rand.New(rand.NewSource(42))
fmt.Println(wdRand.Intn(100))
fmt.Println(wdRand.Intn(100))
fmt.Println(wdRand.Intn(100))
}
https://go.dev/play/p/Sp0Wfx0Bkbb
Now everytime you call the code, the results become identical.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论