2017-12-02 115 views
-1

考虑这段代码:通过在字符串文字上调用`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<'_>>> 

我知道,我不能在我的结构/功能的定义,类型,因为it doesn't have an explicit lifetime...

我怎样才能正确地写这个代码?

回答

1

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

documentation for str::chars告诉你它到底是什么类型:

fn chars(&self) -> Chars 

It produces a type mismatch error

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

How can I correctly write this 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 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,因为没有合适的特征。

because it doesn't have an explicit lifetime

您不必关心寿命,那将覆盖通用。如果您的类型需要知道它是可见的,只需将它放在您的结构中:

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()); 
} 
相关问题