如何在Rust中某个范围内生成随机数?

How can I generate a random number within a range in Rust?

Editor's note: This code example is from a version of Rust prior to 1.0 and is not syntactically valid Rust 1.0 code. Updated versions of this code produce different errors, but the answers still contain valuable information.

我遇到了以下示例,该示例说明了如何使用Rust生成随机数,但似乎不起作用。 该示例未显示其适用于Rust的哪个版本,因此它可能已过时,或者我弄错了。

1
2
3
4
5
6
7
8
9
10
11
12
// http://static.rust-lang.org/doc/master/std/rand/trait.Rng.html

use std::rand;
use std::rand::Rng;

fn main() {
    let mut rng = rand::task_rng();
    let n: uint = rng.gen_range(0u, 10);
    println!("{}", n);
    let m: float = rng.gen_range(-40.0, 1.3e5);
    println!("{}", m);
}

当我尝试对此进行编译时,将导致以下错误:

1
2
3
4
5
6
7
8
test_rand002.rs:6:17: 6:39 error: type `@mut std::rand::IsaacRng` does not
implement any method in scope named `gen_range`
test_rand002.rs:6    let n: uint = rng.gen_range(0u, 10);
                                   ^~~~~~~~~~~~~~~~~~~~~~
test_rand002.rs:8:18: 8:46 error: type `@mut std::rand::IsaacRng` does not
implement any method in scope named `gen_range`
test_rand002.rs:8    let m: float = rng.gen_range(-40.0, 1.3e5);
                                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~

在上面的同一页面上,还有另一个有效的示例(如下)。 但是,尽管可以适应,但它并不能完全满足我的要求。

1
2
3
4
5
6
7
8
9
use std::rand;
use std::rand::Rng;

fn main() {
    let mut rng = rand::task_rng();
    let x: uint = rng.gen();
    println!("{}", x);
    println!("{:?}", rng.gen::<(f64, bool)>());
}

如何在给定范围内(例如:0到n)使用Rust(例如:i64)生成"简单"随机数?


这将使用Rng::gen_range生成一个介于0和100之间的随机数:

1
2
3
4
5
6
7
8
9
extern crate rand; // 0.6.5

use rand::Rng;

fn main() {
    // Generate random number in the range [0, 99]
    let num = rand::thread_rng().gen_range(0, 100);
    println!("{}", num);
}

不要忘记将rand依赖项添加到Cargo.toml:

1
2
[dependencies]
rand ="0.6.5"


Editor's note: This answer is for a version of Rust prior to 1.0 and is not valid in Rust 1.0.

最近这已经发生了很大的变化(对不起!都是我),在Rust 0.8中它被称为gen_integer_range(请注意URL中的/0.8/而不是/master/,如果您使用的是0.8,则需要 阅读这些文档)。

一个警告词:.gen_integer_range在许多方面都是完全错误的,新的.gen_range没有错误问题。

主机代码(.gen_range正常工作):

1
2
3
4
5
6
7
use std::rand::{task_rng, Rng};

fn main() {
    // a number from [-40.0, 13000.0)
    let num: f64 = task_rng().gen_range(-40.0, 1.3e4);
    println!("{}", num);
}


Rng::gen_range的文档指出:

This function is optimised for the case that only a single sample is made from the given range. See also the Uniform distribution type which may be faster if sampling from the same range repeatedly.

Uniform可用于生成单个值:

1
2
3
4
5
6
7
8
use rand::distributions::{Distribution, Uniform}; // 0.6.5

fn main() {
    let step = Uniform::new(0, 50);
    let mut rng = rand::thread_rng();
    let choice = step.sample(&mut rng);
    println!("{}", choice);
}

操场

或生成值的迭代器:

1
2
3
4
5
6
7
8
use rand::distributions::{Distribution, Uniform}; // 0.6.5

fn main() {
    let step = Uniform::new(0, 50);
    let mut rng = rand::thread_rng();
    let choices: Vec<_> = step.sample_iter(&mut rng).take(10).collect();
    println!("{:?}", choices);
}

操场