让我们说我有矢量,我想要保持偶数元素.我需要用cloned()
和filter()
.例如:
fn main() { let my_vec: Vec= vec![1,2,3,4]; let my_vec_1: Vec = my_vec.iter().cloned().filter(|&x| x % 2 == 0).collect(); println!("{:?}", my_vec_1); let my_vec_2: Vec = my_vec.iter().filter(|&x| x % 2 == 0).cloned().collect(); println!("{:?}", my_vec_2); }
两种方法都有效.使用cloned()
after filter()
看起来效率更高一些.因为那时我不必将迭代器的所有元素转换&T
为T
,而只转换已经过滤的元素.在我的例子中,这是元素的一半.
但是,我似乎看到cloned()
之前申请过filter()
.这是一个例子:method.inspect
我认为可能.cloned()
必须在之前使用没有实现Copy
特征的类型,但似乎并非如此:嵌套的vec示例.此外,因为过滤器使用FnMut(&Self::Item)
,我认为这应该是一个问题.
cloned()
以前使用有优势filter()
吗?这更像是一个风格问题吗?如果是这样,是否有首选风格?
这是Matthieu M.答案的替代品.
当你有小Copy
元素时,你应该Clone
尽快使用它们.在这些情况下,克隆几乎总是免费的,但我看到额外的间接混淆了优化器.当你调用iter
一个整数容器时,cloned
除非你可以将它合并到下一个调用中,否则应该几乎总是跟随它.通过额外的解除引用来呼叫map
.
因此,在给定的情况下,cloned
早期使用是完全合理的.确实,这是一个微优化,但它很容易做到并且经常使类型更容易使用,所以我认为这样做没有任何缺点.
将来,copied
可能会成为处理此问题的首选方式.
使用非Copy
类型时,Clone
可能不那么便宜,延迟克隆是一个更好的默认值.
这不是风格问题.
这个例子inspect
是show-case inspect
,就是全部.它.cloned
以一种可以说是愚蠢的方式使用,但cloned
可能是因为它易于理解的语义而被选择,以便创建一个易于理解的"复杂的迭代器序列".
那么,.cloned()
之前还是之后.filter(...)
?正如你所提到的,除非克隆是必要的过滤(这将是令人惊讶的),经验法则将是克隆后,以便最小化克隆元素的数量.
这里没有风格,只是一个务实的绩效评估.