Why don't we implement all the functions from

2019-07-07 05:33发布

问题:

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

回答1:

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.