2015-04-21 88 views
1

我試圖根據一個選項輸入切換到一個函數的行爲。這個想法是根據給定的選項是否存在來迭代。這裏有一個最低限度,如果傻,例如:迭代幾個可能的迭代器之一

fn main() { 
    use std::iter; 
    let x: Option<i64> = None; 

    // Repeat x 5 times if present, otherwise count from 1 to 5 
    for i in match x { None => 1..5, Some(x) => iter::repeat(x).take(5) } { 
     println!("{}", i); 
    } 
} 

我得到一個錯誤的類型匹配武器是不相容的。一個是Range類型,另一個是Take類型。當然,這是非常有意義的,但是我真的很想根據條件選擇我的迭代器,因爲for循環中的代碼是非平凡的,並且複製粘貼所有這些只是爲了更改迭代器選擇會很漂亮醜陋和難以維護。

我試着用兩個手臂上的as Iterator<Item = i64>(或者說,Item =我實際使用的類型),但是這給了我一個關於未分類類型的錯誤,因爲它是一個特徵對象。有沒有簡單的方法去解決這個問題?

編輯:我當然可以使用.collect(),因爲它們返回相同的類型並遍歷該向量。這是一個很好的快速解決方案,但對於大型列表來說似乎有點過分。

回答

5

你需要有一個參照特質

use std::iter; 

fn main() { 
    let mut a; 
    let mut b; 

    let x: Option<i64> = None; 

    // Repeat x 5 times if present, otherwise count from 1 to 5 
    let i: &mut Iterator<Item=i64> = match x { 
     None => { 
      a = 1..5; 
      &mut a 
     }, 
     Some(x) => { 
      b = iter::repeat(x).take(5); 
      &mut b 
     }, 
    }; 

    for i in i { 
     println!("{}", i); 
    } 
} 

該解決方案的主要缺點是,你必須分配堆棧空間,讓您有每個具體類型。這也意味着每種類型的變量。一件好事是隻有被使用的類型需要被初始化。