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

▼魔方 西西 提交于 2019-12-12 03:27:12

问题


I have the following code:

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
    }

}

The idea is that the graph creates a new node and "lends" it to someone who calls the method. But I can not figure out how to return a reference to the newly created structure. The second return is working fine, but obviously not effective.

How to return a node without taking it back from the vector?


回答1:


Here's why you can't 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];
}

Here's a sample output:

0x7fffc36a3418
0x7f4c96c2d000

As you can see, &node and &self.nodes[index] return completely different values. Moreover, &node (0x7fffc36a3418) will be invalid as soon as create_node returns, because this address points to create_node call frame, and a call frame is freed when a function returns.




回答2:


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

You can't. This is one of the basic errors which are ruled out by the ownership system.

Suppose you could. Then when your function returns such reference will point to destroyed memory.

You can read more on ownership in the official guide on ownership. It explains how ownership and borrowing work, including why your program is incorrect.

BTW, unless you have #[derive(Copy)] on your Node, taking a reference to node won't work also because node is moved into the vector. Ownership guide explains move semantics as well.



来源:https://stackoverflow.com/questions/27841657/how-to-return-a-pointer-to-owned-value-that-does-not-live-long-enough

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!