简体   繁体   中英

How to generate random instance of custom struct in Rust?

Using the rand crate , I can generate random values for built-in types using rand::random() . How can I provide the same functionality for my own types?


In the following code, rand::random() fails to generate an instance of type Id .

struct Id(u32);
pub fn main() {
    let _: u32 = rand::random(); // works
    let _: Id = rand::random(); // fails to compile
}

Instead, it fails with this error

   Compiling playground v0.0.1 (/playground)
error[E0277]: the trait bound `Standard: Distribution<Id>` is not satisfied
   --> src/main.rs:4:17
    |
4   |     let _: Id = rand::random(); // fails to compile
    |                 ^^^^^^^^^^^^ the trait `Distribution<Id>` is not implemented for `Standard`
    |
    = help: the following other types implement trait `Distribution<T>`:
              <Standard as Distribution<()>>
              <Standard as Distribution<(A, B)>>
              <Standard as Distribution<(A, B, C)>>
              <Standard as Distribution<(A, B, C, D)>>
              <Standard as Distribution<(A, B, C, D, E)>>
              <Standard as Distribution<(A, B, C, D, E, F)>>
              <Standard as Distribution<(A, B, C, D, E, F, G)>>
              <Standard as Distribution<(A, B, C, D, E, F, G, H)>>
            and 62 others
note: required by a bound in `random`
   --> /playground/.cargo/registry/src/github.com-1ecc6299db9ec823/rand-0.8.5/src/lib.rs:184:17
    |
184 | where Standard: Distribution<T> {
    |                 ^^^^^^^^^^^^^^^ required by this bound in `random`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground` due to previous error

As the error suggests, you merely need to implement Distribution<Id> for Standard . The docs here say how to do that.

use rand::{
    distributions::{Distribution, Standard},
    prelude::*,
};

#[derive(Debug)]
struct Id(u32);

impl Distribution<Id> for Standard {
    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Id {
        Id(rng.gen())
    }

    // other methods in Distribution are derived from `sample`
}

pub fn main() {
    let rand_id = rand::random::<Id>();
    println!("{:?}", rand_id); // Id(2627542617)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM