Reputation: 21
I am new to rust and was going over iterators and this where I got blocked.So if I am implementing Iterator directly and not IntoIterator,how come I am able to call into_iter (and too multiple times).My understanding is if I implemented IntoIterator,I should be going to Iterator via into_iter.But if I am able to implement Iterator,why do I still need into_iter(would be called implicitly if i didnt give I guess for for in )
struct StrSplit<'a> {
rest: &'a str,
delim: &'a str,
}
impl<'a> StrSplit<'a> {
fn new(haystack: &'a str, delim: &'a str) -> Self {
Self {
rest: haystack,
delim,
}
}
}
impl<'a> Iterator for StrSplit<'a> {
type Item = &'a str;
fn next(&mut self) -> Option<Self::Item> {
let to_return;
if let Some(next) = self.rest.find(self.delim) {
to_return = &self.rest[..next];
self.rest = &self.rest[next + self.delim.len() + 1..];
return Some(to_return);
} else if !self.rest.is_empty() {
to_return = self.rest;
self.rest="";
return Some(to_return);
}
return None;
}
}
fn main() {
let check = StrSplit::new("this was to check what was to be checked", "was");
let iterr = check.into_iter().into_iter().into_iter();
for part in iterr {
println!("{}", part);
}
}
Upvotes: 1
Views: 696
Reputation: 9617
If you're new to Rust this might be a bit subtle, but it's a thing that you'll see quite often with the traits of the standard library:
You correctly note that into_iter
is a method of the IntoIterator
trait. You also note that you implemented Iterator
for your struct, but not IntoIterator
. So what gives?
Checking the methods defined on Iterator
, there's no into_iter
to be found.
But now if you check the documentation for IntoIterator
, and scroll down to the list of Implementors https://doc.rust-lang.org/std/iter/trait.IntoIterator.html#implementors
you will find the following snippet:
impl<I> IntoIterator for I
where
I: Iterator
This is called a blanket implementation: For any type T
that implements the Iterator
trait, there will be automatically an implementation for the IntoIterator
trait!
Because your struct implements Iterator
, it also gets IntoIterator
implemented.
There's some other examples of this in the standard library. For example, if you implement From<A>
for some type B
, you automatically get the Into<B>
trait implemented for type A
.
Another example is ToString
:
impl<T> ToString for T where
T: Display + ?Sized,
Any type that implements the Display
trait gets the ToString
trait for free!
Upvotes: 3