简体   繁体   中英

Why do I get the error “the trait `Iterator` is not implemented” for a reference to a generic type even though it implements IntoIterator?

In the following example, MyTrait extends IntoIterator but the compiler doesn't recognize it when used in a loop.

pub trait MyTrait: IntoIterator<Item = i32> {
    fn foo(&self);
}

pub fn run<M: MyTrait>(my: &M) {
    for a in my {
        println!("{}", a);
    }
}

I get the error:

error[E0277]: `&M` is not an iterator
 --> src/lib.rs:6:14
  |
6 |     for a in my {
  |              ^^ `&M` is not an iterator
  |
  = help: the trait `Iterator` is not implemented for `&M`
  = note: required because of the requirements on the impl of `IntoIterator` for `&M`
  = note: required by `into_iter`

Only M implements IntoIterator , but you're trying to iterate over a &M , which doesn't have to.

It's not clear what you hope to achieve with run , but removing the reference might be a start:

pub fn run<M: MyTrait>(my: M) {
    for a in my {
        println!("{}", a);
    }
}

Note that M itself may be (or contain) a reference, so writing it in this way doesn't mean you can't use it with borrowed data. Here's one way to use run to iterate over a &Vec ( playground ):

impl<I> MyTrait for I
where
    I: IntoIterator<Item = i32>,
{
    fn foo(&self) {}
}

fn main() {
    let v = vec![10, 12, 20];
    run(v.iter().copied());
}

This uses .copied() to turn an Iterator<Item = &i32> to an Iterator<Item = i32> .

Related questions

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM