1

I have a function:

fn take_iter<
    LABEL: std::fmt::Debug,
    DATA: std::fmt::Debug,
    SAMPLE: IntoIterator<Item = DATA>,
    I: Iterator<Item = (SAMPLE, LABEL)>,
>(
    iter: I,
) {
    for (sample, label) in iter {
        print!("sample {:.?}: ", label);
        for val in sample {
            print!("{:.?} ", val);
        }
        println!();
    }
}

Example usage:

let a: Vec<(Vec<u8>, u16)> = vec![(vec![1, 2, 3, 4], 2), (vec![1, 2, 3, 4], 4)];
take_iter(a.into_iter());

Prints:

sample 2: 1 2 3 4 
sample 4: 1 2 3 4 

My goal is to adapt this function to take the values by reference rather than by value:

let a: Vec<(Vec<u8>, u16)> = vec![(vec![1, 2, 3, 4], 2), (vec![1, 2, 3, 4], 4)];
take_iter(a.iter());

My current attempt (Rust playground) is:

fn take_iter<
    LABEL: std::fmt::Debug,
    DATA: std::fmt::Debug,
    SAMPLE: IntoIterator<Item = DATA>,
    K: std::ops::Deref<Target = (SAMPLE, LABEL)>,
    I: Iterator<Item = K>,
>(
    iter: I,
) {
    for t in iter {
        let (sample, label) = &*t;
        print!("sample {:.?}: ", label);
        for val in sample.iter() {
            print!("{:.?} ", val);
        }
        println!();
    }
}

This gives the error:

error[E0599]: no method named `iter` found for reference `&SAMPLE` in the current scope
  --> src/main.rs:30:27
   |
30 |         for val in sample.iter() {
   |                           ^^^^ method not found in `&SAMPLE`

What am I doing wrong here?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Jonathan Woollett-light
  • 2,813
  • 5
  • 30
  • 58
  • 2
    `IntoIterator` does not define a method called `iter()`. – Shepmaster Aug 10 '21 at 17:34
  • @Shepmaster Would you happen to know how to improve implementation I have below? I can't figure out a way that `Iterator::Item` for generic `I` can work for both `&(SAMPLE,LABEL)` and `(SAMPLE,LABEL)`. – Ian Graham Aug 11 '21 at 15:10
  • 1
    [The duplicate applied to your situation](https://play.integer32.com/?version=stable&mode=debug&edition=2018&gist=0316f7a397f5aa39feabe42fec12d5fc). – Shepmaster Aug 11 '21 at 15:32
  • @IanGraham see above. – Shepmaster Aug 11 '21 at 15:33
  • 1
    @Shepmaster Ah, thank you! It is difficult applying these advanced concepts to various cases. I appreciate your time with the help :) – Ian Graham Aug 11 '21 at 15:39
  • 1
    @IanGraham no problem. I was close yesterday with my suggestions to use HRTB, but dealing with the associated type projection caused an error I was unfamiliar with. Luckily, there was a rust-lang/rust issue about it that linked back to dtolnay's answer on the related question, which made solving it easy. Then it was just a matter of cleaning up the usage of `Deref` and other little things. – Shepmaster Aug 11 '21 at 15:43

1 Answers1

-1

IntoIterator trait has only into_iter() method, not iter(). Also you have to call it on an owned value, not a reference.

In generic code you can only call methods of traits your function requires, and nothing else, so it doesn't matter that Vec has .iter().

Kornel
  • 97,764
  • 37
  • 219
  • 309