2017-12-02 113 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()); 
} 
相關問題