thosphor
thosphor

Reputation: 2781

Passing array to function: array must have 'Sized' type

I've constructed an array of arrays like this:

let mut my_array = [[false; WIDTH]; HEIGHT];

where WIDTH and HEIGHT are previously defined constants.

I want to pass the whole array to a function, and change the values within the array, although not the size/length of the array.

I've tried:

array_func(&my_array);  // (in main function)

fn array_func(arr: &mut [[bool]]) {
    println!("{:?}", arr);
}

And I get the error:

the trait 'std::marker::Sized' is not implemented for '[bool]'
note: `[bool]` does not have a constant size known at compile-time
note: slice and array elements must have `Sized` type

The size of my array should be known at compile time - I can't change the size of an array. At least, I thought the let mut my_array meant I could change the values within the array but not the size of the array.

Upvotes: 2

Views: 5028

Answers (1)

Matthieu M.
Matthieu M.

Reputation: 300349

the trait 'std::marker::Sized' is not implemented for '[bool]'

There are essentially 2 forms of arrays in Rust:

  • [T; N] is an array of N Ts, it is Sized.
  • [T] is an array of T of size only known at run-time, it is NOT Sized, and can only really be manipulated as a slice (&[T]).

The problem you have in your code is that in [[bool]], the inner [bool] is therefore NOT Sized, and only Sized elements can be stored in an array.

The simplest solution is probably to update your function signature to correctly annotate the array sizes:

fn array_func(arr: &mut [[bool; WIDTH]; HEIGHT]) {
}

It is possible to coerce a &[T; N] to a &[T], so you could also use:

fn array_func(arr: &mut [[bool; WIDTH]]) {
}

However, it is NOT possible to coerce a [[T; N]] to [&[T]], and thus, not possible to coerce a &[[T; N]; M] into a &[&[T]; M] (and thus &[&[T]]), because an array and a reference to an array have a different memory representation and thus this would be an O(M) operation (and require a new array of size M).

At least, I thought the let mut my_array meant I could change the values within the array but not the size of the array.

This is correct indeed, the dimensions of the array are part of its type, and mut only allows changing the value not the type.

Upvotes: 6

Related Questions