Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return an array in Rust function

Tags:

arrays

rust

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);
}
like image 380
Mateusz Piwowarski Avatar asked Dec 03 '19 19:12

Mateusz Piwowarski


People also ask

How do I return an array in Rust?

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 f64 s) is a different type from [f64; 99] .

How do you print an array in Rust?

To print an array in Rust, we use the 😕 Operator inside the println! function.

How do you return a function in Rust?

The return keyword can be used to return a value inside a function's body. When this keyword isn't used, the last expression is implicitly considered to be the return value. If a function returns a value, its return type is specified in the signature using -> after the parentheses () .

Does Rust have array?

Editions. Prior to Rust 1.53, arrays did not implement IntoIterator by value, so the method call array. into_iter() auto-referenced into a slice iterator. Right now, the old behavior is preserved in the 2015 and 2018 editions of Rust for compatibility, ignoring IntoIterator by value.


1 Answers

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.

like image 160
asky Avatar answered Oct 10 '22 05:10

asky