2016-02-12 23 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可能不会这么便宜的工作,延缓克隆是一个更好的默认值。

相关问题