I can implement Iterator
trait for my struct, and get IntoIterator
implemented for free, thanks to the blanket implementation.
struct Foo {}
impl Iterator for Foo {
type Item = ();
fn next(&mut self) -> Option<Self::Item> { None }
}
fn bar(foo: Foo) {
foo.into_iter(); // implemented automatically for my struct
}
But why can I also do this?
fn bar(foo: &mut Foo) {
foo.into_iter(); // works; but shouldn't into_iter require ownership?
}
The implementation of the into_iter method seems to require ownership of the value:
impl<I: Iterator> const IntoIterator for I {
type Item = I::Item;
type IntoIter = I;
#[inline]
fn into_iter(self) -> I {
self
}
}
What allows the method into_iter to accept mutable reference when it is defined to take ownership?
Is there a way to make the method move_out
in the following example to behave like the method into_iter
?
trait A {}
trait B {
fn move_out(self) -> Self;
}
impl<T: A> B for T {
fn move_out(self) -> Self {
self
}
}
struct Foo {}
impl A for Foo {}
fn bar(foo: &mut Foo) {
foo.move_out(); // compile error
}
It's pretty straight forward any type T
that implements Iterator
also implements Iterator
for &mut T
. And all types implementing Iterator
implement IntoIterator
which allows you to call into_iter
on them in the first place.
You can make A
and B
behave the same way by simply adding the same blanket implementation Iterator
has:
impl<T: A> A for &mut T {}