我正在编写一个函数,将内容从一个Vec
传输到另一个。
我设法写了两个不同版本的相同代码。一个更干净,但可能更慢。
版本1:
fn move_values<T>(buffer: &mut Vec<T>, recipient: &mut Vec<T>) {
loop {
let value = buffer.pop();
if value.is_none() {
return;
}
recipient.push(value.unwrap());
}
}
第2版:
fn move_values<T>(buffer: &mut Vec<T>, recipient: &mut Vec<T>) {
for value in buffer.iter() {
recipient.push(value.clone());
}
buffer.clear();
}
我最初的直觉是版本1更快,因为它只需要一次通过缓冲区;而版本2更“生锈”,因为它涉及迭代集合而不是使用loop
。
一般来说,哪一种更惯用或“更好的做法”?
注意,我知道append
,我正在尝试用手进行教育。
答案 0 :(得分:3)
都不是。有一个内置的操作,Vec::append
:
将其他元素移动到
Self
,将其他元素留空。
fn move_values<T>(buffer: &mut Vec<T>, recipient: &mut Vec<T>) {
recipient.append(buffer);
}
你的两个函数都没有编译:
fn move_values_1<T>(buffer: &mut Vec<T>, recipient: &mut Vec<T>) {
loop {
let value = buffer.pop();
if value.is_none() {
return;
}
recipient.push_front(card.unwrap());
}
}
error[E0425]: unresolved name `card`
--> src/main.rs:7:30
|
7 | recipient.push_front(card.unwrap());
| ^^^^ unresolved name
fn move_values_2<T>(buffer: &mut Vec<T>, recipient: &mut Vec<T>) {
for value in buffer.iter() {
recipient.push_front(value.clone());
}
buffer.clear();
}
error: no method named `push_front` found for type `&mut std::vec::Vec<T>` in the current scope
--> src/main.rs:7:19
|
7 | recipient.push_front(card.unwrap());
| ^^^^^^^^^^
如果我自己实施
嗯,这是为你实施的原因,但是确定......让我们深入了解。
通过模式匹配检查是否通常可以避免is_some
或is_none
。例如:
fn move_values_1<T>(buffer: &mut Vec<T>, recipient: &mut Vec<T>) {
while let Some(v) = buffer.pop() {
recipient.push(v);
}
}
当然,这会以反向顺序移动所有内容,因为推送和弹出到Vec都会发生在最后。
调用clone
并不能达到你想要的效果,除非你的特质界限表明T
实现了Clone
。否则,您只是克隆引用本身。
如果从一个集合中排除值并将它们插入另一个集合中,则可以避免克隆的需要:
for value in buffer.drain(..) {
recipient.push(value);
}
但是for
循环是愚蠢的,只使用迭代器的extend
集合:
recipient.extend(buffer.drain(..));
我仍然使用内置的append
方法在同一类型的集合之间进行传输时,因为它可能针对精确的数据布局进行了优化,并且可能是专门的对于某些类型的数据。