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
),则无法更改此事实-但是,原始节点将不可用,因为它已移动。。。。。。所以你需要参考新的地方,而不是旧的地方。