通过字符串文字上调用“ chars”方法产生的类型/特征是什么?



考虑此代码:

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());
}

它产生类型不匹配错误:

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`

numstr.chars().cycle().peekable()的类型是什么?编译器告诉我,它的全部类型是:

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

我知道我无法在结构/函数的定义中使用该类型,因为它没有明确的寿命...

如何正确编写此代码?

通过在字符串文字上调用 chars方法产生的类型/特征是什么?

str::chars的文档告诉您它是什么类型:

fn chars(&self) -> Chars

它产生类型不匹配错误

是的,因为您尚未指定T的具体类型。您已经引入了一个完全独立的通用类型U,并且没有参考T的参数或返回类型。编译器的上下文可用于推断T是什么。

如何正确编写此代码?

删除无用的额外类型参数:

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());
}

我已经删除了nextcollect的实现,因为它们有我不在乎解决的其他无关错误。我还将initialize重命名为new,因为new是在没有多个构造函数的情况下的标准构造函数。

注意到peekable的使用完全没有用。通用类型T不知道可以致电peek,因为没有适当的特征来限制。

因为它没有明确的寿命

您不必关心一生,这将被通用性覆盖。如果您的类型需要知道它是可窥视的,那么只需将其放在您的结构中:

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());
}

最新更新