The official tour of Go gives the following code in the sandbox:
package main
import (
"fmt"
"math/rand"
)
func main() {
fmt.Println("My favorite number is", rand.Intn(10))
}
And this instruction:
Note: the environment in which these programs are executed is deterministic, so each time you run the example program rand.Intn will return the same number. (To see a different number, seed the number generator; see rand.Seed.)
After reading the entry under the official documentation for rand.Seed and reading this answer, I still can't correctly seed the random number generator.
Can someone please demonstrate how the rand.Seed function should be used to seed the random number generator?
Many thanks, Jon
By default rand.Intn
uses the globalRand.Intn. Its created internally, refer here. So when you set via rand.Seed
rand.Seed(time.Now().UTC().UnixNano())
Then globalRand
uses the new seed value.
When needed you can create your own rand generator with seed value. Refer to godoc example.
Play Link (without seed): https://play.golang.org/p/2yg7xjvHoJ
Output:
My favorite number is 1
My favorite number is 7
My favorite number is 7
My favorite number is 9
My favorite number is 1
My favorite number is 8
My favorite number is 5
My favorite number is 0
My favorite number is 6
Play Link (with seed): https://play.golang.org/p/EpW6R5rvM4
Output:
My favorite number is 0
My favorite number is 8
My favorite number is 7
My favorite number is 2
My favorite number is 3
My favorite number is 9
My favorite number is 4
My favorite number is 7
My favorite number is 8
EDIT:
As @AlexanderTrakhimenok mentioned, in playground program execution is deterministic
. However, the playground doesn't stop you from supplying rand.Seed
value.
Remember Seed value is int64
.
When you rand.Intn
, it uses default seed value 1
for globalRand
.
var globalRand = New(&lockedSource{src: NewSource(1).(Source64)})
And in playground time.Now().UTC().UnixNano()
gives you same value 1257894000000000000
since the start time is locked to a constant
. But it is different from default seed value, that's why second playground link produces the different result.
So above two would produce the same result always.
How should we change the result in playground?
Yes, we can. Let's supply UnixNano()
value 1500909006430687579
to rand.Seed
, which is generated from my machine.
Play Link: https://play.golang.org/p/-nTydej8YF
Output:
My favorite number is 3
My favorite number is 5
My favorite number is 3
My favorite number is 8
My favorite number is 0
My favorite number is 5
My favorite number is 4
My favorite number is 7
My favorite number is 1