如何 return 指向 "does not live long enough" 拥有的值的指针?

How to return a pointer to owned value that "does not live long enough"?

我有以下代码:

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
    }

}

想法是图创建一个新节点,然后 "lends" 将它提供给调用该方法的人。但我不知道如何 return 引用新创建的结构。第二个 return 工作正常,但显然无效。

如何 return 一个节点而不从向量中取回它?

But I can not figure out how to return a reference to the newly created structure.

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

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

您可以在 official guide on ownership 中阅读有关所有权的更多信息。它解释了所有权和借用的工作原理,包括您的程序不正确的原因。

顺便说一句,除非您的 Node 上有 #[derive(Copy)],否则引用 node 也不会起作用,因为 node 已移入向量中。所有权指南也解释了移动语义。

这就是为什么你不能 return &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]return是完全不同的值。而且,&node(0x7fffc36a3418)一过create_nodereturns就会失效,因为这个地址指向create_node调用帧,函数调用时释放一个调用帧returns.