【问题标题】:How can I generate a random number within a range in Rust?如何在 Rust 中生成一个范围内的随机数?
【发布时间】:2013-10-30 00:47:21
【问题描述】:

编者注:此代码示例来自 Rust 1.0 之前的版本,在语法上不是有效的 Rust 1.0 代码。此代码的更新版本会产生不同的错误,但答案仍然包含有价值的信息。

我遇到了如何使用 Rust 生成随机数的以下示例,但它似乎不起作用。该示例没有显示它适用于哪个版本的 Rust,所以它可能已经过时,或者我有什么问题。

// 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);
}

当我尝试编译它时,会出现以下错误:

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);
                                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~

在同一页面(上方)上还有另一个示例(如下)确实有效。然而,它并没有完全符合我的要求,尽管我可以调整它。

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)生成“简单”随机数?

【问题讨论】:

标签: random rust rust-obsolete


【解决方案1】:

这会使用Rng::gen_range 生成一个介于 0(含)和 100(不含)之间的随机数:

use rand::Rng; // 0.8.0

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

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

[dependencies]
rand = "0.8"

【讨论】:

  • 这甚至不会编译编译器说没有方法 gen_rng rand::prelude::ThreadRng
  • @nikoss 你需要安装 rand crate。正如我所说,将其添加到 cargo.toml
【解决方案2】:

编者注:此答案适用于 Rust 1.0 之前的版本,在 Rust 1.0 中无效。请参阅 Manoel Stilpen's answer

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

警告:.gen_integer_range 在很多方面完全不正确,新的.gen_range 没有错误问题。


master 代码(.gen_range 工作正常):

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);
}

【讨论】:

  • 我看到 0.10 和 master 文档对 use rand::Rng static.rust-lang.org/doc/0.10/rand/index.html 说,所以这可能是一个文档错误
  • 我在std::randrust.rs:1 中得到rust.rs:1:17: 1:25 error: unresolved import std::rand::task_rng. There is no task_rng` 使用std::rand::{task_rng, Rng}; ^~~~~~~~ 错误:当我尝试使用rustc 1.0.0-nightly (b4c965ee8 2015-03-02) (built 2015-03-03)编译时,由于先前的错误`而中止
  • 对于现在偶然发现这个问题的人:rand 似乎已经成为一个独立的板条箱,下面 Manoel Stilpen 的答案,你明确使用该板条箱,工作。跨度>
【解决方案3】:

Rng::gen_range 的文档指出:

此函数针对从给定范围仅生成单个样本的情况进行了优化。另请参阅Uniform 分布类型,如果重复从同一范围内采样,可能会更快。

Uniform 可用于生成单个值:

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);
}

Playground

或者生成一个值的迭代器:

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);
}

Playground

【讨论】:

  • 在 Rust 1.15.1 中,我从 rand::thread_rng 得到“未解析的名称”。 play.rust-lang.org/…
  • 我认为自从每个答案甚至文档都使用 rand::thread_rng 以来,情况都发生了变化。顺便说一句,rand 现在不稳定,所以您必须将#![feature(rand)] 添加到文件顶部并使用 nightly rustc。我想做的就是测试一些东西;我这个接近于通过 FFI 使用 C rand() 函数并称之为一天。
  • 这对我来说适用于 Rust 1.7.0。不过必须将rand = "0.3" 添加到Cargo.toml 文件中。
  • 从 rustc 1.42.0 (stable) with > rand 0.7 开始,这似乎是最准确的答案。
【解决方案4】:

为什么不直接使用模数?

let x = rng.gen<u32>() % 25

因此您的值将介于 0 和 24 之间。如果您需要不同的范围,请添加偏移量。

【讨论】:

    猜你喜欢
    • 2018-04-08
    • 1970-01-01
    • 2011-08-02
    • 2019-10-30
    • 1970-01-01
    • 1970-01-01
    • 2014-01-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多