How to re-use a Range multiple times without cloning it?

Viewed 387

I have some working code to sum a Range and then use it again later in a for loop. Is it possible to make the code below work without having to clone the Range?

let range = 0..10;
let sum = range.clone().sum::<i8>();
println!("{}", sum);

for data in range.step_by(2).enumerate() {
   println!("{:?}", data);
}
2 Answers

Range<T> is an iterator. Rust iterators are usually:

Refer to @mcarton's answer for a general explanation, but if you're just learning Rust and experimenting with toy examples then simpler version of your code would be to just declare the Range twice:

fn main() {
    let sum: i32 = (0..10).sum();
    println!("{}", sum);
    
    for data in (0..10).step_by(2).enumerate() {
        println!("{:?}", data);
    }
}

If you were writing a function that accepted the Range as an argument then you would have to clone (or be creative in consolidating both loops):

fn fun(mut range: Range<i32>) {
    let sum: i32 = range.clone().sum();
    println!("{}", sum);
    
    for data in range.step_by(2).enumerate() {
        println!("{:?}", data);
    }
}

Regardless, cloning a Range is not a big deal because it's only two integers:

pub struct Range<Idx> {
    pub start: Idx,
    pub end: Idx,
}

So whether you're cloning a 0..10 or a 0..1000000 they're all the same size and the clone operation will be fast and cheap.

Related