2016-02-12 51 views
2

假設我有矢量,我只想保留偶數元素。我需要使用cloned()filter()。例如:應將.cloned()放在.filter()之前或之後

fn main() { 
    let my_vec: Vec<i32> = vec![1,2,3,4]; 

    let my_vec_1: Vec<i32> = my_vec.iter().cloned().filter(|&x| x % 2 == 0).collect(); 
    println!("{:?}", my_vec_1); 

    let my_vec_2: Vec<i32> = my_vec.iter().filter(|&x| x % 2 == 0).cloned().collect(); 
    println!("{:?}", my_vec_2); 

} 

兩個辦法工作。在filter()後使用cloned()似乎效率更高一點。因爲那樣我不必將迭代器的所有元素從&T轉換爲T,但只能轉換已經過濾的元素。在我的例子中,這是一半的元素。

但是,我似乎在filter()之前應用了cloned()。這裏有一個例子:method.inspect

我想,也許.cloned()有不實現Copy特質類型被使用過,但它似乎並沒有這樣的情況:nested vec example。另外,因爲過濾器使用FnMut(&Self::Item),我不認爲這應該是一個問題。

filter()之前使用cloned()有什麼好處?這更多是一個風格問題嗎?如果是這樣,是否有首選風格?

回答

5

這不是一個風格問題。

inspect的例子是顯示案例inspect,就是這樣。它使用.cloned的方式很愚蠢,但可能選擇cloned是因爲它容易理解語義以便創建一個容易理解的「複雜迭代器序列」。


那麼,.cloned()之前或之後.filter(...)?正如你所提到的,除非克隆過濾是必要的(這將是令人驚訝的),經驗法則是在克隆之後進行克隆,以便最小化克隆元件的數量。

這裏沒有風格,只是一個務實的業績考覈。

3

這是一個替代Mattieu M.的答案。

當你有小,Copy元素,你應該Clone他們儘快。在這些情況下克隆幾乎總是免費的,但我看到額外的間接混淆了優化器。當你在一個整數容器上調用iter時,cloned應該幾乎總是遵循它,除非你可以將它合併到下一個調用中,例如。通過致電map的額外解除引用。

所以在給出的情況下,早期使用cloned是完全明智的。這確實是一種微型優化,但它很容易實現,並且通常使得類型更簡單,所以我認爲沒有缺點。


當與非Copy類型,其中Clone可能不會這麼便宜的工作,延緩克隆是一個更好的默認值。

相關問題