wind2412
wind2412

Reputation: 1069

How to use another array's length to initialize an array in Rust?

I want to initialize an array whose length is equal to another array's length:

fn foo(array: &[i32]) {
    let mut sum = [0; array.len()];
}

It will make an error:

error[E0080]: constant evaluation error
  --> test.rs:22:18
   |
22 |    let mut sum = [0; array.len()];
   |                      ^^^^^^^^^^^ unsupported constant expr

I think I must use this len() argument... How can I solve this?

Upvotes: 5

Views: 1890

Answers (2)

Shepmaster
Shepmaster

Reputation: 430681

To answer the question asked:

How to use another array's length to initialize an array in Rust?

As of Rust 1.51, you can write generic code like:

fn foo<const N: usize>(array: [u8; N]) -> [u8; N] {
    unimplemented!()
}

See Is it possible to control the size of an array using the type parameter of a generic? for further details.

The solution for previous versions of Rust involves a combination of traits and macros. This has the distinct disadvantage of being limited to a set of types. This is discussed further in questions like Why does println! work only for arrays with a length less than 33?


Showcasing the shorter, more idiomatic version of the Vec-based code:

fn foo(slice: &[i32]) {
    let mut sum = vec![0; slice.len()];
}

Upvotes: 5

user1804599
user1804599

Reputation:

You are actually taking the length of a slice, not an array. Array lengths must be known at compile time. array.len(), being the length of a slice, is potentially derived from runtime input, and as such cannot be used as an array length. You can create a vector instead. For example:

use std::iter::repeat;

fn foo(slice: &[i32]){
    let mut sum: Vec<i32> = repeat(0).take(slice.len()).collect();
    // ......
}

Upvotes: 2

Related Questions