可变和不可变数据访问

时间:2016-10-09 16:11:20

标签: rust

这个问题可能非常基本,但我甚至不知道要搜索什么。 在The Book中我没有看到任何跳出来的东西,而且我是Rust的初学者:

struct Node;
impl Node {
    fn children(&mut self) -> &mut Vec<Node> {
        // Pulls a field out of Node, to be mutated
    }
    fn next_node(&self) -> Node {
        // Produces a new value using values computed from self.
        // Doesn't hold a reference to self
    }
}
[...]
if self.children().len() > K {
    let mut next_node = self.next_node();
    let list = self.children();
    // something involving next_node and list
}

这就是我最终让Rust相信我所做的事情还可以。 我发现更直接的是:

let list = self.children();
if list.len() > K {
    let mut next_node = self.next_node();
    // Something involving next_node and list
}

但它抱怨是因为我无法在self中获得next_node的不可变引用,因为self.children中已经有一个可变的引用,这是真的。< / p>

特别是在这个实现中,我只做.children()一次,在这种情况下,这不是一个非常复杂的方法,但可能是。

有没有办法做到这一点,不会多次计算children,并且在不需要时不会构建next_node

1 个答案:

答案 0 :(得分:1)

答案简单:没有

Rust可以在借用时推断出不相交的字段,因此你可以可变地借用一个字段然后借用另一个字段并且它将起作用,只要两者都出现在同一个上下文中(函数/方法) )。

在这种情况下,next_node对编译器的作用是不透明的,实际上它可能正在使用我们所知道的所有子代。

因此,要求在调用next_node时没有未付的可变借款。

  

特别是在这个实现中,我只做.children()一次,在这种情况下,这不是一个非常复杂的方法,但可能是。

是的......但是这种方法的责任是什么。为什么它会执行两个广泛的计算借用?

此代码的简单组织将是:

  • 做一次昂贵的计算(不借用)
  • 借用尽可能小的范围

它会起作用:

self.expensive_computation();

if self.children.len() > K {
    let mut next_node = self.next_node();
    let list = self.children;
    // Something involving next_node and list
}