随机函数不返回随机值

Mag*_*gin 4 random rust

如果我以这种方式生成 10 个随机数,它会起作用(它会产生不同的值)

fn main() {
    let seed = std::time::SystemTime::now()
        .duration_since(std::time::UNIX_EPOCH)
        .expect("system time cannot be before unix epoch")
        .as_millis() as u64;

    let mut rng = oorandom::Rand32::new(seed);

    for _ in 0..10 {
        println!("Your random number is: {}", &rng.rand_range(0..4));
    }
Run Code Online (Sandbox Code Playgroud)

但如果我将它们分解到一个结构中,生成的值总是相同的:

use oorandom::{self, Rand32};

struct Util {
    rng: Rand32,
}
impl Util {
    pub fn new() -> Self {
        let seed = std::time::SystemTime::now()
            .duration_since(std::time::UNIX_EPOCH)
            .unwrap()
            .as_millis() as u64;
        println!("new color util {}", seed);
        let rng = Rand32::new(seed);
        Util { rng }
    }
    pub fn get_random(&self) -> u32 {
        let mut rng = self.rng;
        let random_number = rng.rand_range(0..4);
        random_number
    }
}

fn main() {
    let util = Util::new();
    for _ in 0..10 {
        println!("Your random number is: {}", util.get_random());
    }
}
Run Code Online (Sandbox Code Playgroud)

这两种使用 API 的方法有什么区别get_random,为什么当我放入rng结构时它会中断?

Bla*_*ans 9

这不起作用,因为您正在复制rng结构,然后对其进行变异(注册您已采样了一个数字):

impl Util {
    pub fn get_random(&self) -> u32 {
        let mut rng = self.rng;  // <-- here you copy `rng`,
                                 // creating a new value, unrelated with `self.rng`
        let random_number = rng.rand_range(0..4); // <-- here you mutate `rng`,
        random_number                             // but leave `self.rng` untouched
    }
}
Run Code Online (Sandbox Code Playgroud)

相反,您必须采用可变借用才能就地self变异:rng

impl Util {
    pub fn get_random(&mut self) -> u32 {
        //             +++ `mut` has been added, to allow mutation of `self`
        let rng = &mut self.rng;  // this does not copy `self.rng`
        let random_number = rng.rand_range(0..4);
        random_number
    }
}
Run Code Online (Sandbox Code Playgroud)

或者,更短的时间

impl Util {
    pub fn get_random(&mut self) -> u32 {
        let random_number = self.rng.rand_range(0..4);
        random_number
    }
}
Run Code Online (Sandbox Code Playgroud)

甚至

impl Util {
    pub fn get_random(&mut self) -> u32 {
        self.rng.rand_range(0..4)
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这就是为什么(与官方 Rust 建议相反)我不太喜欢在每个可以接受它的结构上使用 `#[derive(Copy)]` ...... (3认同)