1

I have a large array which I am slicing using split_at():

let (left, right) = large_array.split_at(i);

I am doing some operation on left and then continuing to slice right in a while loop until right is empty.

// test vector
let v: Vec<u8> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let (left, right) = v.split_at(1); // left = [1], right = [2,3,4 ... 10]
let j: u8 = left[0];
    
for i in 1..10 {
    println!("{} {}", j, right.len()); // prints "1 9" on all iterations
    let (left, right) = right.split_at(1);
    let j: u8 = left[0];
    println!("{} {}", j, right.len()); // prints "2 8" on all iterations
}

Rust playground

Although the length of right changes from 9 to 8 during the first iteration, on the second iteration it returns back to being 9. What's causing this?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Ach113
  • 1,775
  • 3
  • 18
  • 40
  • 2
    You're not changing `right`, you're just temporarily shadowing it, so why would the result change? Do you mean `right.split_at(i)`? In your loop you do `right.split_at(1)`, `1`, not `i`. – tadman Sep 22 '20 at 17:05
  • [The duplicates applied to your situation](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=d19cf482cd57ec0db917ff5ed671565d). – Shepmaster Sep 22 '20 at 17:09
  • 1
    @tadman the `1` is correct because `right` should always be getting smaller, and OP wants to take the first value. – Shepmaster Sep 22 '20 at 17:10
  • @tadman, I dont think splitting index really matters for the sake of this example. What I dont understand is why `right` is being only temporarily shadowed here. – Ach113 Sep 22 '20 at 17:11
  • @Shepmaster, your example confuses me even more lol. I thought `let (left, right) = right.split_at(1);` would act same as what you have suggested. Why isnt right getting updated in the first case (or why is it only getting updated temporarily) – Ach113 Sep 22 '20 at 17:12
  • 2
    [I'd write it like this](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=0d15d2e86faa26f53100eb99eafb6ff1) personally. – Shepmaster Sep 22 '20 at 17:12
  • 1
    @Ach113 that's the definition of "shadowing". You've created a new variable with the same name as another variable, hiding ("shadowing") the first. Your original code is equivalent [to this](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=b0920370a5581e5b272be271f02cefd2). – Shepmaster Sep 22 '20 at 17:15
  • @Shepmaster, thanks. I just reviewed the links you have provided and it has made some things clearer – Ach113 Sep 22 '20 at 17:16
  • It's worth noting that in Rust you essentially can't change a variable once it's defined unless it's `mut`, and these aren't set that way. `let` always creates a *new* variable that may share the same name, which has the effect of shadowing, but it's actually unrelated to the original. – tadman Sep 22 '20 at 17:18
  • @shepmaster, @tadman so if I understand this correctly the original instance of `right` gets created before while loop. Inside the loop a shadowed variable is created which gets discarded after each iteration. – Ach113 Sep 22 '20 at 17:28
  • That is correct. – Shepmaster Sep 22 '20 at 17:29

0 Answers0