0

Consider this piece of code:

struct Collector<T>
where
    T: Iterator<Item = char>,
{
    current: u32,
    right_neighbour: u32,
    counter: usize,
    iterator: T,
}

impl<T: Iterator<Item = char>> Collector<T> {
    fn next(&self) -> u32 {
        self.iterator
            .next()
            .expect("failed to get next digit!")
            .to_digit(10)
            .expect("failed to prase char as digit!")
    }

    fn collect(&self) {
        self.current = self.right_neighbour;
        self.right_neighbour = self.next();
        self.counter = self.counter + 1;
    }

    fn initialize<U>(iterator: U) -> Collector<U>
    where
        U: Iterator<Item = char>,
    {
        let mut collector = Collector {
            current: 0,
            right_neighbour: 0,
            counter: 0,
            iterator: iterator,
        };

        collector.collect();

        collector
    }
}

fn main() {
    let numstr = "1111";

    let mut collector = Collector::initialize(numstr.chars().cycle().peekable());
}

It produces a type mismatch error:

error[E0284]: type annotations required: cannot resolve `<_ as std::iter::Iterator>::Item == char`
  --> src/main.rs:46:25
   |
46 |     let mut collector = Collector::initialize(numstr.chars().cycle().peekable());
   |                         ^^^^^^^^^^^^^^^^^^^^^
   |
   = note: required by `<Collector<T>>::initialize`

What is the type of numstr.chars().cycle().peekable()? The compiler tells me that its full type is:

std::iter::Peekable<std::iter::Cycle<std::str::Chars<'_>>>

I know that I can't use that type in the definition of my structs/functions, because it doesn't have an explicit lifetime...

How can I correctly write this code?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
bzm3r
  • 3,113
  • 6
  • 34
  • 67

1 Answers1

1

What is the type/trait produced by calling the chars method on a string literal?

The documentation for str::chars tells you exactly what type it is:

fn chars(&self) -> Chars

It produces a type mismatch error

Yes, because you haven't specified what the concrete type of T should be. You've introduced a completely separate generic type U and have no arguments or return types that reference T. The compiler has zero context to use to infer what T is.

How can I correctly write this code?

Remove the useless extra type parameter:

struct Collector<T>
where
    T: Iterator<Item = char>,
{
    current: u32,
    right_neighbour: u32,
    counter: usize,
    iterator: T,
}

impl<T: Iterator<Item = char>> Collector<T> {
    fn new(iterator: T) -> Collector<T> {
        let mut collector = Collector {
            current: 0,
            right_neighbour: 0,
            counter: 0,
            iterator: iterator,
        };

        collector.collect();

        collector
    }

    fn collect(&self) {
        unimplemented!()
    }

    fn next(&self) -> u32 {
        unimplemented!()
    }
}

fn main() {
    let numstr = "1111";

    let mut collector = Collector::new(numstr.chars().cycle().peekable());
}

I've removed the implementations of next and collect because they have other, unrelated errors that I don't care to fix. I also renamed initialize to new, as new is the standard constructor name in the absence of multiple constructors.

Of note is that the usage of peekable here is completely useless. The generic type T doesn't know that it's possible to call peek because there's no appropriate trait bound for such.

because it doesn't have an explicit lifetime

You don't have to care about the lifetime, that will be covered by the generic. If your type needed to know that it was peekable, just put that in your struct:

struct Collector<T>
where
    T: Iterator<Item = char>,
{
    // ...
    iterator: std::iter::Peekable<T>,
}

impl<T: Iterator<Item = char>> Collector<T> {
    fn new(iterator: T) -> Collector<T> {
        let mut collector = Collector {
            // ...
            iterator: iterator.peekable(),
        };

        // ...
    }

    // ...
}

fn main() {
    // ...
    let mut collector = Collector::new(numstr.chars().cycle());
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366