30

I want to create a function that generates an array of X size with random values.

use rand::prelude::*;

fn generateArray(howManyValues: u32)->[f64]
{
    let mut rng = rand::thread_rng();
    let array: [f64, howManyValues];
    for i in 0..howManyValues
    {
        array[i] = rng.gen()*100;
    }

    println!("{:?}", array);
    return array;
}

fn main() {
    generateArray(10);
}
0

3 Answers 3

38

I want to create a function that generates an array of X size with random values.

The type [f64] is a slice, not an array. An array needs a length, like [f64; 25].

Rust's Vec is probably better than a array or slice for this job, unless you're using some sort of foreign function interface (FFI), or a Rust API requires an array (it probably requires Deref<Target = [T]>, basically generic over all array-like types including Vec and arrays). Vec is analogous to C++'s std::vector, and Java's ArrayList.

use rand::prelude::*;

fn generate_vec(len: usize) -> Vec<f64> {
    let mut rng = rand::thread_rng();
    let mut vec = Vec::with_capacity(len);
    for _ in 0..len {
        vec.push(rng.gen::<f64>() * 100.);
    }
    return vec;
}

fn main() {
    let generated_vec = generate_vec(10);
    println!("{:?}", generated_vec);
}

I made some style changes[1]. If you really want an array, read on.

If you know the size of the array at compile time, you can use an array. If it is too big to fit on the stack, you'll get a stack overflow. Rust 1.51 made this slightly more ergonomic with const generics.

use rand::prelude::*;

fn generate_array<const LEN: usize>() -> [f64; LEN] {
    let mut rng = rand::thread_rng();
    let mut arr = [0.; LEN];
    for item in arr.iter_mut() {
        *item = rng.gen::<f64>() * 100.;
    }
    arr
}

fn main() {
    // generate_array can make an array of any length (within stack size limits)
    let generated_array1:[f64; 5] = generate_array();
    let generated_array2:[f64; 10] = generate_array();
    println!("{:?}", generated_array2);
}

If you don't know the length at compile time, or it is too big to fit on the stack, the closest you can get to an array is Box<[T]> (Box of slice of T) using into_boxed_slice().

use rand::prelude::*;

fn generate_array(len: usize) -> Box<[f64]> {
    let mut rng = rand::thread_rng();
    let mut vec = Vec::with_capacity(len);
    for _ in 0..len {
        vec.push(rng.gen::<f64>() * 100.);
    }
    vec.into_boxed_slice()
}

fn main() {
    let generated_array = generate_array(10);
    println!("{:?}", generated_array);
}

[1] words in function names separated with underscores instead of camelCase, moved println to main() and changed the type of len to usize, since this is how arrays are typically indexed in Rust.

Sign up to request clarification or add additional context in comments.

1 Comment

unless you're using some sort of foreign function interface (FFI) — The concept of an array doesn't exist in the C ABI, so this is a non-sequitur.
1

Adapting your function, and still returning an array, requires specifying the number of elements in the return type i.e. fn generateArray()->[f64; 100]. The rust type system accounts for the size of an array, so [f64; 100] (an array of length 100 containing f64s) is a different type from [f64; 99]. Specifying the array's length in the function makes is less reusable, as it always returns the same size array.

If you simply must create stack-allocated arrays full of random floats, you could use a macro, but this limits you to array sizes known at compile time (constexpr in C++ lingo, const in Rust lingo). I consider this macro approach slightly unidiomatic rust. The macro could look like

use rand::prelude::*;

macro_rules! make_array {
    ($size:literal) => {{
        let mut rng = rand::thread_rng();
        let mut arr = [0_f64; $size];
        for item in arr.iter_mut() {
            *item = rng.gen::<f64>()*100.;
        }
        arr
    }}
}

fn main() {
    let arr = make_array!(32);
    println!("{:?}", arr);
    let arr = make_array!(16);
    println!("{:?}", arr);
}

This is more reusable than the modified function, as you can specify different numbers of elements.

Comments

1

First, like other programming languages array in Rust cannot grow or shrink. You can either use a vector.

let v : Vec<i32> = Vec::new();

you can use .push() function to push values in vector.

8 Comments

what language have an array that can grow or shrink ?
I don't know much about other languages but Python has arrays called "lists" which can grow and shrink.
so not array, list is list not array
yeah javascript is... well, actually when you push something on an array in javascript you create a new array, in javascript all is const, anyway you get my point, array often mean "fixed size" because that how thing are since 50 years, that why a lot of other lang use name like vector, list to represent contiguous element. Also, this is very important in language like C where array are something very precise and a lot of poeple still wrongly use the word array. So I would say "like other programming languages array in Rust cannot grow or shrink" :p
Q: "what language have an array that can grow or shrink ?" A: python: docs.python.org/2.7/library/array.html
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.