How to create random vector using generic?

What I want is to have one helper function to return a random vector:

let i32_vec = gen_random_vec<i32>(100);
let f32_vec = gen_random_vec<f32>(10); 
// etc

I wrote the following code but it can't make the compiler happy :frowning:

use rand::distributions::{Distribution};
use rand::Rng;

pub fn gen_random_vec<T>(size: usize) -> Vec<T>
where
    T: Distribution,
{
    let mut res: Vec<T> = Vec::with_capacity(size);
    let mut rng = rand::thread_rng();
    for i in 0..size {
        let x : T = rng.gen();
        res.push(x);
    }
    res
}

ref: https://rust-random.github.io/rand/rand/trait.Rng.html

Would be appreciate if somebody can help me complete the helper function.

let mut res = vec![T::default(); size];
rand::thread_rng().fill(&mut res);
res

https://rust-random.github.io/rand/rand/trait.Rng.html#method.fill

1 Like

When asking about a compile error, please include the compiler error message. It often contains useful information that can help the people here identify the problem, such as an error code or the line containing the issue.

at least OP included the complete code, so getting the error is rather trivial:

error[E0107]: wrong number of type arguments: expected 1, found 0
 --> src/lib.rs:6:8
  |
6 |     T: Distribution,
  |        ^^^^^^^^^^^^ expected 1 type argument

See, when you look into the docs for Distribution you’ll find its declaration to be

pub trait Distribution<T> { ... }

(admitted, this declaration may be collapsed by default)

What this means is, the trait has a type parameter. What types that implement Distribution<T> are? The docs say:

Types (distributions) that can be used to create a random instance of T .

See, there’s actually 2 types involved here. One, the type of object you want to generate, T in these docs as well as you code, and then a type that specifies the kind of distribution you want.

Well, you may say you don’t specify any distribution and dont want to? I guess you’re right, you’re using Rng::gen() which doesn’t appear to offer any way to specify special kinds of distributions anyways... but let’s look at its documentation, too, it has the type

fn gen<T>(&mut self) -> T
where
    Standard: Distribution<T>, 

So there’s your clue, just use Standard: Distribution<T> yourself, too (gotta also import rand::distributions::Standard for this) and your code compiles!

1 Like

(Meta: including the error text also helps future people find it, and hopefully the solution, in case they have the same problem.)

2 Likes

Thanks, everybody!

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.