Rust Notes #9: An Interesting Finding While Exploring iter::repeat_n()

rust
Author

Jerry Wu

Published

July 24, 2026

Rust Notes 9

I found an interesting detail while reading the documentation of iter::repeat_n().

Here’s a simplified example from the docs:

use std::iter;

fn main() {
    let v: Vec<i32> = Vec::with_capacity(123);
    let mut it = iter::repeat_n(v, 2);

    // The first item is produced by cloning the stored value.
    // Note that Vec::clone() copies elements, not the spare capacity.
    let cloned = it.next().unwrap();
    assert_eq!(cloned.len(), 0);
    assert_eq!(cloned.capacity(), 0);

    // The final item is the original value moved out of the iterator.
    // This avoids an unnecessary clone.
    let last = it.next().unwrap();
    assert_eq!(last.len(), 0);
    assert_eq!(last.capacity(), 123);

    // No more items remain.
    assert_eq!(None, it.next());
}

iter::repeat_n(v, 2) takes ownership of v. In other words, v is moved into the iterator, and the iterator becomes responsible for producing the repeated values.

For the first next() call, repeat_n() clones the stored value using Vec::clone(). However, the cloned vector does not preserve the original vector’s spare capacity. Since the original vector has a capacity of 123 but contains no elements, the cloned vector has a capacity of 0.

The interesting part happens on the final next() call. Instead of cloning the value one more time, repeat_n() moves the original vector out of the iterator and returns it directly.

This means repeat_n() only needs to perform n - 1 clones and can use the original value for the last item. It is a small but elegant optimization made possible by Rust’s ownership system.

WarningDisclaimer

This post was drafted by me, with AI assistance to refine the content.