To implement an iterator in Rust, we only need to implement the next method, as explained in the documentation. However, the Iterator trait has many more methods.
As far as I know, we need to implement all the methods of a trait. For instance, this does not compile (playground link):
struct SomeStruct {}
trait SomeTrait {
fn foo(&self);
fn bar(&self);
}
impl SomeTrait for SomeStruct {
fn foo(&self) {
unimplemented!()
}
}
fn main() {}
The error is pretty clear:
error[E0046]: not all trait items implemented, missing: `bar`
--> src/main.rs:8:1
|
5 | fn bar(&self);
| -------------- `bar` from trait
...
8 | impl SomeTrait for SomeStruct {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `bar` in implementation
Because every method on Iterator except next has a default implementation. These are methods implemented in the trait itself, and implementors of the trait gain them "for free":
struct SomeStruct {}
trait SomeTrait {
fn foo(&self);
fn bar(&self) {
println!("default")
}
}
impl SomeTrait for SomeStruct {
fn foo(&self) {
unimplemented!()
}
}
fn main() {}
You can tell if a trait method has a default implementation or not through the documentation:
Required methods
fn next(&mut self) -> Option<Self::Item>Provided methods
fn size_hint(&self) -> (usize, Option<usize>)
Note that size_hint is in the "provided methods" section — that's the indication that there's a default implementation.
If you can implement the method in a more efficient way, you are welcome to do so, but note that it is not possible to call the default implementation if you decide to override it.
Specifically for Iterator, it's a great idea to implement size_hint if you can, as that can help optimize methods like collect.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With