首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >了解克隆借用

了解克隆借用
EN

Stack Overflow用户
提问于 2021-04-16 05:32:38
回答 1查看 66关注 0票数 0

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

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

代码语言:javascript
复制
fn main() {
    let mut v = vec![1, 1, 1];
    let mut c = Vec::new();

    for i in &mut v {
        *i += 1;
        c.push(v.clone());
    }

    println!("{:?}", v);
}

这会产生以下错误

代码语言:javascript
复制
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

在一些方便的rust书的帮助下,我能够解释错误消息。我相信这告诉我,我不能同时拥有一个可变的和一个不可变的引用,这两个引用都是活动的。迭代地创建数据结构的副本并更新所述数据结构中的引用的rust惯用方法是什么(或有没有)?

编辑:上面的例子可能太小了,没有突出我遇到的实际问题。什么是生锈惯用的方式来写一些类似下面的例子。

代码语言:javascript
复制
#[derive(Clone, Debug)]
enum Tree {
    Leaf,
    Node { l: Box<Tree>, r: Box<Tree>, },
}

fn main() {
    let mut tree = Tree::Node {
      l: Box::new(Tree::Node { l: Box::new(Tree::Leaf), r: Box::new(Tree::Leaf), }),
      r: Box::new(Tree::Node { l: Box::new(Tree::Leaf), r: Box::new(Tree::Leaf), }),
    };
    let augmenting_trees = vec![
        Tree::Node { l: Box::new(Tree::Leaf), r: Box::new(Tree::Leaf), },
        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), }), },
    ];

    let mut trees: Vec<Tree> = Vec::new();
    let leaf = find_some_leaf_in_tree(&mut tree);
    for augmenting_tree in augmenting_trees {
        *leaf = augmenting_tree;
        trees.push(tree.clone());
    }

    println!("trees: {:?}", trees);
}

fn find_some_leaf_in_tree<'a>(tree: &'a mut Tree) -> &'a mut Tree {
    match tree {
        Tree::Leaf => tree,
        Tree::Node { l, .. } => find_some_leaf_in_tree(l),
    }
}
EN

回答 1

Stack Overflow用户

发布于 2021-04-16 08:44:38

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

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

代码语言:javascript
复制
fn main() {
    let mut v = vec![1, 1, 1];
    let mut c = Vec::new();

    for i in 0..v.len() {
        v[i] += 1;
        c.push(v.clone());
    }

    dbg!(v, c);
}

请注意,这并不意味着您完全不能使用引用。例如,代码可以用对v的可变引用来编写:

代码语言:javascript
复制
fn modify_and_snapshot(v: &mut Vec<u32>) -> Vec<Vec<u32>> {
    let mut c = Vec::new();
    for i in 0..v.len() {
        v[i] += 1;
        c.push(v.clone());
    }
    c
}

fn main() {
    let mut v = vec![1, 1, 1];
    let c = modify_and_snapshot(&mut v);
    dbg!(v, c);
}

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67116302

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档