Subsetting array and array size at compile time?

When trying this:

let numbers = [1, 1, 2, 3, 5, 8, 13];
let numbers_subset = numbers[0..=3];

The resulting error, which I expected, is:

let numbers_subset = numbers[0..=3];
    |         ^^^^^^^^^^^^^^ doesn't have a size known at compile-time
help: consider borrowing here
    |
116 |     let numbers_subset = &numbers[0..=3];

My reasoning was, that shadowing the numbers variable with numbers_subset would make it no longer possible to count elements in numbers.

But in that case I can' explain why the following is possible:

let numbers = [1, 1, 2, 3, 5, 8, 13];
let numbers_subset = numbers[3];

In both cases there is shadowing and there is counting, iterating. So why the difference?

Probably I'm missing something very simple here...

What do you mean by "shadowing"? Shadowing in rust refer to the action of creating a new variable with the same name as an existing variable. In your case there are just two variables, with different names, so by Rust terms there's no shadowing.

As to why one works and the other doesnt, numbers[0..=3] doesn't create an array, but a slice. It's just a view with no statically (i.e. at compile time) size. This is why the compiler tells you "doesn't have a size known at compile-time". numbers[3] however is just a single element, of type i32, whose size is statically known and can thus be held in a variable.

There's no shadowing, counting or iterating involved in any of the two cases.

3 Likes

Thanks, @SkiFire13, indeed, this is not shadowing. I mistakenly took it for shadowing. Still, I don't understand why using a reference does work:

let numbers = [1, 1, 2, 3, 5, 8, 13];
let numbers_subset = &numbers[0..=3];

Assuming that, also here, a slice is created.

A slice in this case is simply a part of memory already used by numbers, the only thing you create is a reference to that memory.

4 Likes

And, as usual in Rust, a non-mutable (ie. shared) borrow still lets you use the original. Whereas

let mut a = [1, 2, 3, 4]; // mut so we can mutably borrow
let b = &mut a[1..3];

locks you out of a as long as b lives.

2 Likes

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.