英文:
How can I let a function randomly return either a true or a false in go
问题
我想要一个函数,每次调用时返回一个随机的true
或false
:
function randBoolean() {
return Math.random() < 0.5;
}
randBoolean(); // true
randBoolean(); // false
randBoolean(); // false
randBoolean(); // true
你可以使用Math.random()
函数生成一个介于0和1之间的随机数,然后通过比较这个随机数是否小于0.5来返回true
或false
。这样每次调用randBoolean()
函数时都会返回一个随机的布尔值。
英文:
I want to have a function that I can call to get a random true
or false
on each call:
randBoolean() // true
randBoolean() // false
randBoolean() // false
randBoolean() // true
How can I return a random boolean?
答案1
得分: 19
你需要一些随机信息,并根据其值,在可能的情况下返回true
的一半,返回false
的另一半。
一个非常简单的例子是使用math/rand
包中的rand.Float32()
函数:
func rand1() bool {
return rand.Float32() < 0.5
}
不要忘记使用rand.Seed()
正确地初始化math/rand
包,以便在每次应用程序运行时都能得到不同的结果:
func main() {
rand.Seed(time.Now().UnixNano())
fmt.Println(rand1())
}
math/rand
包的文档中提到了这一点:
如果需要每次运行时都有不同的行为,请使用Seed函数初始化默认的Source。
如果不进行初始化,每次应用程序运行时都会返回相同的伪随机信息。
一些变体:
func rand2() bool {
return rand.Int31()&0x01 == 0
}
func rand3() bool {
return rand.Intn(2) == 0
}
还有一种有趣的解决方案,不使用math/rand
包,而是使用select
语句:
func rand9() bool {
c := make(chan struct{})
close(c)
select {
case <-c:
return true
case <-c:
return false
}
}
解释:
select
语句从可以立即执行而不会阻塞的情况中随机选择一个。由于从已关闭的通道接收可以立即执行,因此将随机选择其中一个情况,返回true
或false
。请注意,这并不是完全随机的,因为select
语句并不要求完全随机。
通道也可以移动到全局变量中,这样就不需要在每次调用时创建和关闭通道:
var c = make(chan struct{})
func init() {
close(c)
}
func rand9() bool {
select {
case <-c:
return true
case <-c:
return false
}
}
英文:
You need some kind of random information, and based on its value, you can return true
in half of its possible cases, and false
in the other half of the cases.
A very simple example using rand.Float32()
of the math/rand
package:
func rand1() bool {
return rand.Float32() < 0.5
}
Don't forget to properly seed the math/rand
package for it to be different on each app run using rand.Seed()
:
func main() {
rand.Seed(time.Now().UnixNano())
fmt.Println(rand1())
}
This is mentioned in the package doc of math/rand
:
> Use the Seed function to initialize the default Source if different behavior is required for each run.
If you don't seed, the same pseudo-random information is returned on each application run.
Some variations:
func rand2() bool {
return rand.Int31()&0x01 == 0
}
func rand3() bool {
return rand.Intn(2) == 0
}
And an interesting solution without using the math/rand
package. It uses the select
statement:
func rand9() bool {
c := make(chan struct{})
close(c)
select {
case <-c:
return true
case <-c:
return false
}
}
Explanation:
The select
statement chooses one random case from the ones that can proceed without blocking. Since receiving from a closed channel can proceed immediately, one of the 2 cases will be chosen randomly, returning either true
or false
. Note that however this is far from being perfectly random, as that is not a requirement of the select
statement.
The channel can also be moved to a global variable, so no need to create one and close one in each call:
var c = make(chan struct{})
func init() {
close(c)
}
func rand9() bool {
select {
case <-c:
return true
case <-c:
return false
}
}
答案2
得分: 2
这个函数返回一个布尔值,如果随机整数是偶数,则返回true,否则返回false:
func randBool() bool {
return rand.Int() % 2 == 0
}
英文:
This function returns true if the random integer is even else it returns false:
func randBool() bool{
return rand.Int() % 2 == 0
}
答案3
得分: 1
最简单的方法是生成一个随机数,然后对2取模。如果结果为0,则返回true;如果结果为1,则返回false。
英文:
The easiest way will be to create a random number and then take its modulus of 2. Then if it is 0 the return true and if it is 1 then return false.
答案4
得分: 0
以下是翻译好的内容:
这是另一个一行代码的示例,不需要随机数生成/种子等,非常简单:
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println("Got random bool:", getRandBool())
}
func getRandBool() bool {
now := time.Now()
nowNano := now.Nanosecond()
fmt.Println(nowNano)
return now.UnixNano()%2 == 0
}
在 @icza 的评论之后进行了编辑:time.Now() 应该返回纳秒精度的时间,但在 Windows 10 Pro 64 位上(我尝试过 go 1.8,并且可能适用于其他 Windows 操作系统),它总是返回精度较低的时间(可能是微秒),四舍五入结果以使其以 xxxxx..00 结尾,因此此函数将始终返回 true。我已经修改了函数,以便可以看到结果。在 Linux 上运行良好,可能在其他 Unix 操作系统上也可以正常工作。因此,要么在测试后再使用此函数,要么最好不要在需要部署到 Windows 系统上时使用。这是不幸的,很难相信这一点,但这是现实,是 Windows 的糟糕实现。感谢 @icza 指出这一点。
英文:
Here's another one liner, requires no random number generation/seeding etc., fairly simple :
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println("Got random bool:", getRandBool())
}
func getRandBool() bool {
now := time.Now()
nowNano := now.Nanosecond()
fmt.Println(nowNano)
return now.UnixNano()%2 == 0
}
Edited after @icza's comments : time.Now() is supposed to return time with nanosecond accuracy, but on Windows 10 Pro 64-bit (and I tried with go 1.8 & it may be true with other Windows OS too) it always returns time with lesser precision (probably micro second), rounding off the result so that it'll end with xxxxx..00 and hence this function will return true always. I have modified the function so one can see the result also. Works fine on Linux & probably should on other Unix OS'es too. So either use this function only after testing or better don't use if you need to deploy on a Windows system. It's unfortunate and hard to believe this, but it's a reality, bad Windows implementation. Thanks @icza for pointing out.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论