应该.cloned()之前或之后.filter()

问题描述 投票:4回答:2

比方说,我有载体,我想只保留偶数元素。我需要使用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);

}

这两种方法的工作。使用cloned() filter()似乎更有点快捷的售后服务。因为那时我没有给迭代的所有元素转换从&TT,但只有已过滤的。在我的例子这一半的元素。

但是,我似乎看到cloned()之前应用filter()。这里有一个例子:method.inspect

我想,也许.cloned()有不实现Copy特质类型被使用过,但它似乎并没有这样的情况:nested vec example。同时,由于过滤器使用FnMut(&Self::Item),我不认为这应该是一个问题。

是否有使用cloned() filter()之前的优势?这是更多的是风格的问题的?如果是这样,有最好的风格?

iterator rust
2个回答
6
投票

这不是一个风格问题。

inspect的例子是由显示情况inspect,仅此而已。它采用.cloned在一个可以说是愚蠢的方式,但由于其容易理解语义,从而创建一个易于理解的“复杂的迭代器序列” cloned很可能选择。


所以,.cloned()之前或之后.filter(...)?你提到的,除非克隆是用于过滤必要的(这将是令人惊讶的)的经验法则将后以便最小化克隆的元素数克隆。

这里没有风格,只是一个务实的绩效考核。


7
投票

这是为了Matthieu M.'s answer的替代方案。

当你有小的,Copy元素,你应该尽快Clone他们。克隆是几乎总是免费在这些情况下,但我已经看到了额外的间接混淆了优化。当你调用iter整数的容器上,cloned应该几乎永远是一个遵循它,除非你可以将其合并到下一次调用,例如。是在呼叫额外的解引用到map

因此,在给定的情况下,早期使用cloned是完全合理的。这是真的,这是一个微型的优化,但它是那么容易做到的,往往使各类简单的工作,所以我看不出有什么缺点来这样做。

在未来,copied将有可能成为可用来处理此操作的首选方式。


当与非Copy类型,其中Clone可能不会这么便宜的工作,延缓克隆是一个更好的默认值。

© www.soinside.com 2019 - 2024. All rights reserved.