Как я могу генерировать случайное число в пределах диапазона в Rust?

Примечание редактора: Этот пример кода относится к версии 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)>());
}

Как я могу сгенерировать "простое" случайное число, используя Rust (например, i64) в заданном диапазоне (например, от 0 до n)?

Ответ 1

Примечание редактора: Этот ответ относится к версии Rust до 1.0 и недопустим в Rust 1.0.

Это сильно изменилось в последнее время (извините! Это все я), и в Rust 0.8 он назывался gen_integer_range (обратите внимание на /0.8/ вместо /master/ в URL, если вы используете 0.8, вам нужно читать эти документы).

Предупреждение: .gen_integer_range был совершенно неверным во многих отношениях, новый .gen_range не имеет проблем с некорректностью.


Код для мастера (где .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);
}

Ответ 2

Это генерирует случайное число от 0 до 100, используя Rng::gen_range:

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:

[dependencies]
rand = "0.6.5"

Ответ 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);
}

Детская площадка

Или создать итератор значений:

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

Детская площадка

Ответ 4

Получил это из книги:

extern crate rand;

use rand::Rng;

fn main() {
let num = rand::thread_rng().gen_range(1, 101);
println("The random number is: {}", num)
}

Хотя это работает только для целых чисел.