Usage of by_ref() from Iterator

fn four_byref(a: Vec<i32>)->(i32,i32) {
   let mut v=a.iter(); //v.by_ref=a.iter().byref
  println!(" iterator before{:?}",v);
  let c:i32=v.by_ref().sum();
  println!(" iterator after{:?}",v);
  let d:i32=v.sum();
  return (c,d);
}
output: 
iterator before Iter([1, 8, 3, 4, 10])
 iterator after Iter([ ])
26,0

Here v is a. iter() , so it will take the reference of items in vector. Using by_ref() i passed the reference of iterator to sum method ,so i can use the iterator later.
After sum method we got an empty Iter. Where do the elements go?

Although by_ref doesn't consume the ownership of the iterator, it will iterate the iterator, meaning the elements will be generated and consumed when next is called on the by_ref value.

The by_ref method is mostly useful only when you don't iterate the entire iterator. For example, if used together with take, then any remaining elements are available in the iterator afterwards.

fn four_byref(a: Vec<i32>) {

  let mut v=a.iter(); //v.by_ref=a.iter().byref
  println!(" iterator before{:?}",v);
  for item in v.by_ref(){
      println!("items {item}")
  }
  println!(" iterator after{:?}",v);
  
  for item in v{
      println!("2nd time items {item}")
  }

}
Output:
 iterator before Iter([1, 8, 3, 4, 10])
items 1
items 8
items 3
items 4
items 10
 iterator after Iter([])

What about this case, here after first for loop the Iter is empty. How the vector items are consumed in for loop ?

Iterators return none after all elements of a vec have been read by iterator. (Sometimes they loop back but that does not happen with iterators made from vectors)
This is why you use let mut v=a.iter(); because every time next() is called on a iterator, the iterator changes.

 for item in v.by_ref(){
      println!("items {item}")
  }

The for loop next() function is called when it iterates. So once the final element is read. This v iterator is useless and can only return none in any other for loop.
this happens even when you use by_ref .
look at this piece of code.

fn main(){
    let mut words = ["hello", "world", "of", "Rust"].into_iter();

words.by_ref().next();
//Even when you use by_ref() the state of words changes.
let of_rust: Vec<_> = words.collect();
assert_eq!(of_rust, vec!["world","of", "Rust"]);
}

There are two into-iterators in this case: v.by_ref() and v, where the first one is a mutable reference to an iterator for &Vec (or rather &[i32]), and the second is for Vec. So in these two for-loops, the reference is consumed, and then the Vec is consumed.

let mut v = a.iter() // v: std::slice::Iter
v.by_ref() // v.by_ref() returns &mut std::slice::Iter

You can think by_ref as a way to explicitly get the mutable reference to the iterator (i.e. get &mut Iter) , and then you can call next on it (i.e. Iterator::next(&mut Iter)) .

    fn by_ref(&mut self) -> &mut Self
    where
        Self: Sized,
    {
        self
    }

impl<I> Iterator for &mut I
where
    I: Iterator + ?Sized,

So you can just replace iter.by_ref() by &mut iter under any circumstances.

If you want to consume an iterator and keep using it in its previous state afterwards you need to clone() it or produce a new one from the original collection. The cost of cloning various, a vec::IntoIter involves cloning the entire allocation slice::Iter does not.

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.