【发布时间】:2021-07-11 21:02:09
【问题描述】:
我有一个关于如何将move 变量转换为向量但又不破坏该变量的问题,因为它必须在循环中重复使用。下面说明我的意思:
type Letter = char;
type LetterSet = Vec<Letter>;
fn main() {
let mut v = Vec::<LetterSet>::new();
let mut letterset: LetterSet = LetterSet::new();
for i in 0..5 {
let a = (48 + i as u8) as char;
letterset.push(a);
if i % 2 == 1 {
let b = (65 + i as u8) as char;
letterset.push(b);
} else {
let c = (97 + i as u8) as char;
letterset.push(c);
}
v.push(letterset.clone());
letterset.clear();
}
for letterset in v {
for letter in letterset {
print!("{} ", letter);
}
println!("");
}
}
上面的代码运行。但是,我想避免clone in
v.push(letterset.clone());
letterset.clear();
因为letterset 无论如何都会被清除。相反,我想将它的内容移动到 v 中,但要让它保持活动状态,因为 letterset 必须用于下一次迭代。
我试图删除.clone(),但显然这会导致“移动后借用”错误。我想知道怎么做,谢谢。
【问题讨论】:
-
既然我们谈论的是
Vec<char>,.clone()几乎肯定会编译成一个分配(这是你无法避免的)和一个memcpy()。我真的没有理由避免使用.clone()。要回答这个问题:您可以v.push(letterset.drain(..).collect()),这会将拥有的元素从letterset移动到新的Vec中而不复制它们,留下一个已清除的letterset。同样,这仅在Letter比简单的char更重时才有意义。 -
@user2722968 感谢您的评论。我对
clone(如果正确)的理解是,它将在letterset被清除之前堆分配和复制资源。是的,实际上Letter比玩具示例重得多。 -
在这种情况下,
letterset.clone()将克隆Vec及其所有内容,然后丢弃原件;同样,如果是char,这是非常便宜的,不值得麻烦。.drain()-thingy 将避免克隆,因为它将Letter直接移动到其新位置。也看看下面的答案。
标签: rust clone move vec borrow