Rust 如何返回指向所拥有值的指针;“活得不够长吗?”;?

Rust 如何返回指向所拥有值的指针;“活得不够长吗?”;?,rust,borrow-checker,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 = sel

我有以下代码:

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
    }

}
struct节点{
id:uint
}
结构图{
节点:Vec
}
impl图{
fn new()->图形{
返回图{节点:Vec::new()};
}
fn创建_节点(&mut self)->&node{
设index=self.nodes.len();
设node=node{id:index};
self.nodes.push(节点);
//return&node;//错误:`node`的寿命不够长
return&self.nodes[index];/…但这可以正常工作
}
}
其思想是,该图创建一个新节点,并将其“借给”调用该方法的人。但是我不知道如何返回对新创建的结构的引用。第二次回归效果不错,但显然没有效果

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

但我不知道如何返回对新文档的引用 创建结构

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

我想你可以。然后,当函数返回时,该引用将指向已破坏的内存

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

顺便说一句,除非您的
节点上有
#[导出(复制)]
,否则引用
节点也不会起作用,因为
节点
已移动到向量中。《所有权指南》还解释了移动语义

但我不知道如何返回对新文档的引用 创建结构

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

我想你可以。然后,当函数返回时,该引用将指向已破坏的内存

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


顺便说一句,除非您的
节点上有
#[导出(复制)]
,否则引用
节点也不会起作用,因为
节点
已移动到向量中。《所有权指南》还解释了移动语义。

以下是您无法返回
&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
(0x7fffc36a3418)将在
创建节点
返回时立即无效,因为此地址指向
创建节点
调用帧,当函数返回时调用帧将被释放。

以下是无法返回
&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
(0x7fffc36a3418)在
create\u node
返回时将无效,因为此地址指向
create\u node
调用帧,当函数返回时调用帧将被释放。

您说返回对
Vec
的引用“显然无效”,但我不明白为什么它没有效果。您为什么不想这样做,为什么不能按值返回
节点呢?@DK。我不能按值返回
节点
,因为我之前将其推到了Vector中,正如Vladimir在他的编辑中所说的那样,只需自动派生一个
副本
实现。你说返回对
向量的引用“显然无效”,但我不明白为什么它无效。您为什么不想这样做,为什么不能按值返回
节点呢?@DK。我无法按值返回
节点
,因为我之前将其推入了向量,正如弗拉基米尔在他的编辑中所说的那样,只需自动派生一个
副本
实现。在我的情况下,
节点
图形
一样存在。我是否可以返回一个指针,指向与
&self
具有相同生存期的值?不可以,除非此值已经具有与
self
相同的生存期。这就是为什么将引用返回到向量中是可以的(我真的不明白为什么您不想这样做),但将引用返回到局部变量是不可以的。这确实是一件基本的事情——说
节点
的寿命与
图形
的寿命一样长是不正确的,因为它不存在。它仅在函数调用期间有效,如果不将此值移到其他位置(例如,移到
self
),则无法更改此事实-但是,原始
节点将不可用,因为它已移动。。。。。。因此,您需要引用新的位置,而不是旧的位置。在我的例子中,
节点
图形
一样存在。我是否可以返回一个指针,指向与
&self
具有相同生存期的值?不可以,除非此值已经具有与
self
相同的生存期。这就是为什么将引用返回到向量中是可以的(我真的不明白为什么您不想这样做),但将引用返回到局部变量是不可以的。这确实是一件基本的事情——说
节点
的寿命与
图形
的寿命一样长是不正确的,因为它不存在。它仅在函数调用期间有效,如果不将此值移到其他位置(例如,移到
self
),则无法更改此事实-但是,原始
节点将不可用,因为它已移动。。。。。。所以你需要参考新的地方,而不是旧的地方。