我的Graph
对象的生命周期/借用存在问题。
fn main() {
let mut g = Graph {
nodePointer: &mut 0,
edgePointer: &mut 0,
nodes: &mut Vec::new(),
edges: &mut Vec::new(),
};
let node1 = g.add_node((1, 1));
let node2 = g.get_node(0);
}
pub struct Graph<'a> {
pub nodePointer: &'a mut usize,
pub edgePointer: &'a mut usize,
pub nodes: &'a mut Vec<Node>,
pub edges: &'a mut Vec<Edge>,
}
impl<'a> Graph<'a> {
pub fn add_node(&'a mut self, data: (u64, u64)) -> usize {
let id: usize = *self.nodePointer;
self.nodes.push(Node {
id: id,
datum: data,
});
*self.nodePointer += 1;
return id;
}
pub fn get_node(&'a mut self, id: usize) -> &'a Node {
return &self.nodes[id];
}
pub fn add_edge(&'a mut self, source: u64, target: u64, weight: u16) -> usize {
let id: usize = *self.nodePointer;
self.edges.push(Edge {
id: id,
source,
target,
weight,
});
*self.edgePointer = *self.edgePointer + 1;
return id;
}
}
pub struct Node {
pub id: usize,
pub datum: (u64, u64),
}
pub struct Edge {
pub id: usize,
pub source: u64,
pub target: u64,
pub weight: u16,
}
error[E0499]: cannot borrow `g` as mutable more than once at a time
--> src/main.rs:9:17
|
8 | let node1 = g.add_node((1, 1));
| - first mutable borrow occurs here
9 | let node2 = g.get_node(0);
| ^ second mutable borrow occurs here
10 | }
| - first borrow ends here
答案 0 :(得分:2)
您的问题源于对生命的滥用,特别是在您add_node
的签名中:
pub fn add_node(&'a mut self, data: (u64, u64)) -> usize
在此签名中,您声明add_node
在&'a mut self
上占用Graph<'a>
;换句话说,你告诉Rust这个方法需要在图表的生命周期'a
结束之前不能删除图表。但由于它的图形本身持有对图形的引用,因此删除引用的唯一时间是图形本身被删除。
由于add_node
并不要求您返回对结构中任何对象的引用,因此保持该借用是无关紧要的。如果您更改add_node
方法以删除显式生存期:
pub fn add_node(&mut self, data: (u64, u64)) -> usize
然后您的示例不再引发错误,因为add_node
现在只是借用self
,直到它完成了该功能。 (在幕后,这有效地创建了第二个生命周期'b
并使签名成为&'b mut self
)
请参阅the playground以获取证明。
答案 1 :(得分:0)
考虑一下:
struct Foo<'a> {
x: &'a i32,
}
正如book所述:
那么为什么我们需要一辈子呢?我们需要确保对Foo的任何引用都不能超过它包含的i32的引用。
如果您写的内容如下:
impl<'a> Graph<'a> {
pub fn add_node(&'a mut self, data: (u64, u64)) -> usize {
...
生命周期声明&'a mut self
不是为了将Graph
实例的生命周期与包含的引用相关联,
但是为了声明可变self
引用保持为'a
字段引用声明的相同生命周期Graph
:
fn main() {
let mut g = Graph { // <------------
nodePointer: &mut 0, // |
edgePointer: &mut 0, // lifetime |
nodes: &mut Vec::new(), // of Graph | 'a
edges: &mut Vec::new(), // references |
}; // |
let node1 = Graph::add_node(&mut g, (1, 1)); // |
let node2 = Graph::get_node(&mut g, 0); // |
} //<-------------
g.get_node(0)
被重写为Graph::get_node(&mut g, 0)
,仅仅是为了明确公开&mut
引用
查看'a
的生命周期很明显,引用&mut g
可以多次借用,这会导致错误。