如何返回一个“拥有不够长寿”的拥有值的指针?

时间:2015-01-08 13:48:29

标签: rust borrow-checker

我有以下代码:

struct Node {
    id: uint
}

struct Graph {
    nodes: Vec<Node>
}

impl Graph {

    fn new() -> Graph {
        return Graph { nodes: Vec::new() };
    }

    fn create_node(&mut self) -> &Node {
        let index = self.nodes.len();
        let node = Node { id: index };
        self.nodes.push(node);
        // return &node;           // error: `node` does not live long enough
        return &self.nodes[index]; // ...but this work fine
    }

}

这个想法是图表创建了一个新节点,并且&#34;借出&#34;它给那些调用该方法的人。但我无法弄清楚如何返回对新创建的结构的引用。第二次回归工作正常,但显然效果不佳。

如何在不从向量中取回节点的情况下返回节点?

2 个答案:

答案 0 :(得分:2)

  

但我无法弄清楚如何返回对新的引用   创建结构。

你不能。这是所有权制度排除的基本错误之一。

假设你可以。然后当你的函数返回时,这样的引用将指向被破坏的内存。

您可以在official guide on ownership中详细了解所有权。它解释了所有权和借款的工作方式,包括您的计划不正确的原因。

顺便说一下,除非#[derive(Copy)]上有Node,否则引用node的工作也会因为node被移入向量而失败。所有权指南也解释了移动语义。

答案 1 :(得分:2)

这是您无法返回&node

的原因
fn create_node(&mut self) -> &Node {
    let index = self.nodes.len();
    let node = Node { id: index };
    println!("{}", &node as *const Node);
    self.nodes.push(node);
    println!("{}", &self.nodes[index] as *const Node);
    return &self.nodes[index];
}

这是一个示例输出:

0x7fffc36a3418
0x7f4c96c2d000

如您所见,&node&self.nodes[index]会返回完全不同的值。此外,只要&node返回,create_node(0x7fffc36a3418)就会无效,因为此地址指向create_node调用帧,并且当函数返回时释放调用帧。