Question about Iterator::eq_by

#![feature(iter_order_by)]
#![allow(unused)]
fn main() {
    let xs = [1, 2, 3, 4];
    let ys = [1, 4, 9, 16];
    let it = xs.iter();
    it.eq_by(&ys, |&x, &y| x * x == y);
}

From the Iterator::eq_by signature, mut self is required.
How to explain the above example code?
And the rust docs is conflict with the implemation.

fn eq_by<I, F>(self, other: I, eq: F) -> bool

#[unstable(feature = "iter_order_by", issue = "64295")]
    fn eq_by<I, F>(mut self, other: I, mut eq: F) -> bool
    where
        Self: Sized,
        I: IntoIterator,
        F: FnMut(Self::Item, I::Item) -> bool,

You seem to be confusing mut self and &mut self. The former is actually just self, i.e. an owned argument. The mut is an implementation detail and rightfully not displayed by rustdoc. In general, writing something like

fn foo(mut x: Foo) {
    x.bar();
}

impl Foo {
    fn bar(&mut self) {}
}

is equivalent to

fn foo(arg: Foo) {
    let mut x = arg;
    x.bar();
}

impl Foo {
    fn bar(&mut self) {}
}

similar to how something like

fn baz((a, b): (Baz, Qux)) {
    println!("{} {}", a, b);
}

is equivalent to

fn baz(arg: (Baz, Qux)) {
    let (a, b) = arg;
    println!("{} {}", a, b);
}

The mut self – short for mut self: Self – just means that the local variable that is holding the function argument inside of the body of eq_by is mutable. As mentioned, an implementation detail, nothing you’ll have to worry about as the caller. The function could equivalently have been implemented as

    fn eq_by<I, F>(self, other: I, mut eq: F) -> bool
    where
        Self: Sized,
        I: IntoIterator,
        F: FnMut(Self::Item, I::Item) -> bool,
    {
        let mut this = self;
        let mut other = other.into_iter();

        loop {
            let x = match this.next() {
                None => return other.next().is_none(),
                Some(val) => val,
            };

            let y = match other.next() {
                None => return false,
                Some(val) => val,
            };

            if !eq(x, y) {
                return false;
            }
        }
    }

It`s clear for me now. In fact I just thought self and &self just like the this pointer of C++ class before. So it makes me confused a lot. :grinning:

Associated Items - The Rust Reference (rust-lang.org)

Thanks.

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.