Rust 理解克隆借用

Rust 理解克隆借用,rust,clone,mutable,borrow,Rust,Clone,Mutable,Borrow,我对rust还相当陌生,仍然在学习rust所有权模型。我正在编写一段代码,其中包含对数据结构中某个点的引用。我想存储此数据结构的多个副本,其中每个副本上的参考点都包含不同的值。我(试图)通过在数据结构内部创建一个点的可变引用来解决这个问题,并在每次更新引用后创建原始数据结构的克隆 我能够创建这个简单的示例,它与我正在尝试做的类似,并产生相同的错误 fn main(){ 让mut v=vec![1,1,1]; 让mut c=Vec::new(); 对于i in&mut v{ *i+=1; c、 推

我对rust还相当陌生,仍然在学习rust所有权模型。我正在编写一段代码,其中包含对数据结构中某个点的引用。我想存储此数据结构的多个副本,其中每个副本上的参考点都包含不同的值。我(试图)通过在数据结构内部创建一个点的可变引用来解决这个问题,并在每次更新引用后创建原始数据结构的克隆

我能够创建这个简单的示例,它与我正在尝试做的类似,并产生相同的错误

fn main(){
让mut v=vec![1,1,1];
让mut c=Vec::new();
对于i in&mut v{
*i+=1;
c、 推(v.clone());
}
println!(“{:?}”,v);
}
这将产生以下错误

error[E0502]: cannot borrow `v` as immutable because it is also borrowed as mutable
   --> src/main.rs:107:16
    |
105 |     for i in &mut v {
    |              ------
    |              |
    |              mutable borrow occurs here
    |              mutable borrow later used here
106 |         *i += 1;
107 |         c.push(v.clone());
    |                ^ immutable borrow occurs here
在手边的铁锈书的帮助下,我能够解释错误信息。我相信这告诉我,我不能同时拥有一个可变引用和一个不可变引用。迭代创建数据结构副本并更新所述数据结构内的引用的惯用方法是什么(或是否存在)

编辑: 上面的例子可能太小了,没有突出我遇到的实际问题。下面的例子是怎样写的

#[派生(克隆、调试)]
枚举树{
叶子,
节点{l:Box,r:Box,},
}
fn main(){
让mut tree=tree::Node{
l:Box::new(树::节点{l:Box::new(树::叶),r:Box::new(树::叶),}),
r:Box::new(树::节点{l:Box::new(树::叶),r:Box::new(树::叶),}),
};
让增广树=vec[
树::节点{l:Box::new(树::叶),r:Box::new(树::叶),},
Tree::Node{l:Box::new(Tree::Node{l:Box::new(Tree::Leaf),r:Box::new(Tree::Leaf),}),r:Box::new(Tree::Leaf),},
Tree::Node{l:Box::new(Tree::Leaf),r:Box::new(Tree::Node{l:Box::new(Tree::Leaf),r:Box::new(Tree::Leaf),}),
];
让mut树:Vec=Vec::new();
let leaf=在树(mut tree)(&mut tree)中查找某个叶;
用于在增广_树中增广_树{
*叶=扩充树;
trees.push(tree.clone());
}
println!(“树:{:?}”,树);
}
在树和树上找到一些叶子{
火柴树{
树::叶=>树,
Tree::Node{l,…}=>在树(l)中找到一些叶子,
}
}
迭代创建数据结构副本并更新所述数据结构内的引用的惯用方法是什么(或是否存在)

一般的答案是“不要为了你试图使用参考资料的目的而使用参考资料”。在本例中,您有一个向量,因此使用索引而不是引用:

fn main(){
让mut v=vec![1,1,1];
让mut c=Vec::new();
对于0..v.len()中的i{
v[i]+=1;
c、 推(v.clone());
}
dbg!(v,c);
}
请注意,这并不意味着您根本不能使用引用。例如,代码可以写成对
v
的可变引用:

fn修改_和_快照(v:&mut Vec)->Vec{
让mut c=Vec::new();
对于0..v.len()中的i{
v[i]+=1;
c、 推(v.clone());
}
C
}
fn main(){
让mut v=vec![1,1,1];
设c=修改_和_快照(&mut v);
dbg!(v,c);
}
必要的条件是,当您想要快照
v
时,您对
v
的可变引用不少于全部-您可以拥有整个向量,或者您可以拥有对整个向量的可变引用,但是当存在对部分向量的可变引用时,您不能对整个向量执行任何操作

迭代创建数据结构副本并更新所述数据结构内的引用的惯用方法是什么(或是否存在)

一般的答案是“不要为了你试图使用参考资料的目的而使用参考资料”。在本例中,您有一个向量,因此使用索引而不是引用:

fn main(){
让mut v=vec![1,1,1];
让mut c=Vec::new();
对于0..v.len()中的i{
v[i]+=1;
c、 推(v.clone());
}
dbg!(v,c);
}
请注意,这并不意味着您根本不能使用引用。例如,代码可以写成对
v
的可变引用:

fn修改_和_快照(v:&mut Vec)->Vec{
让mut c=Vec::new();
对于0..v.len()中的i{
v[i]+=1;
c、 推(v.clone());
}
C
}
fn main(){
让mut v=vec![1,1,1];
设c=修改_和_快照(&mut v);
dbg!(v,c);
}

必要的条件是,当您想要快照
v
时,您对
v
的可变引用不少于所有值-您可以拥有整个向量,也可以拥有对整个向量的可变引用,但是,当向量的一部分存在可变引用时,你不能对整个向量做任何事情。

谢谢你的回答。因此,在这种情况下,不要使用引用是有意义的。我更新了我的答案,加入了一个稍微复杂一点的例子,其中引用的使用更有意义。习惯用法仍然是“不要使用引用”吗。如果是这样的话,我如何在没有引用的情况下更新数据结构的一部分?提前感谢您的时间/关注。@CasperLamboo抽象的答案仍然是一样的。对于树的情况,我建议您回滚您的编辑,并发布一个专门关于树的新问题,因为适用于树的策略(或者通常,包含递归的数据结构)具有特定的特征。谢谢您的回答。因此,在这种情况下,不要使用引用是有意义的。我更新了我的答案,加入了一个稍微复杂一点的例子,其中引用的使用更有意义。rust惯用的方式仍然是“不要重复使用”吗