我正在进行一项无法编译的测试:
#[test]
fn node_cost_dequeue() {
let mut queue: BinaryHeap<&NodeCost> = BinaryHeap::new();
let cost_1: NodeCost = NodeCost::new(1, 50, 0);
let cost_2: NodeCost = NodeCost::new(2, 30, 0);
let cost_3: NodeCost = NodeCost::new(3, 80, 0);
queue.push(&cost_1);
queue.push(&cost_2);
queue.push(&cost_3);
assert_eq!(2, (*queue.pop().unwrap()).id);
}
error: cost_1 does not live long enough
附加信息“借款人之前借入的价值下降”。
所以我尝试添加显式的生命周期注释。
#[test]
fn node_cost_dequeue() {
let mut queue: BinaryHeap<&'a NodeCost> = BinaryHeap::new();
let cost_1: NodeCost<'a> = NodeCost::new(1, 50, 0);
let cost_2: NodeCost<'a> = NodeCost::new(2, 30, 0);
let cost_3: NodeCost<'a> = NodeCost::new(3, 80, 0);
queue.push(&cost_1);
queue.push(&cost_2);
queue.push(&cost_3);
assert_eq!(2, (*queue.pop().unwrap()).id);
}
这会产生use of undeclared lifetime name 'a
。
所以,我试图在函数
上声明它fn node_cost_dequeue<'a>() -> () {
但这导致error: functions used as tests must have signature fn() -> ()
我是否在正确的轨道上?我该如何宣布这一生?
答案 0 :(得分:6)
这告诉你的是......
所有内容都以相反的顺序删除。cost_1
将在queue
之前删除..因为它在queue
之后声明。因此queue
引用了cost_1
,因为现在在方法结束时删除了值queue
现在引用了......没有? cost_1
已被删除queue
仍处于“活着状态” - 即使它即将被删除。
要清楚,事件序列很重要,因为BinaryHeap
实例正在存储引用。它没有自己的内容。
事件的顺序是:
BinaryHeap
实例。cost_1
,cost_2
和cost_3
,其引用将插入BinaryHeap
。BinaryHeap
。cost_3
。cost_2
。cost_1
。BinaryHeap
引用现在指向什么?这些项目已被删除。 BinaryHeap
。上面列表中的粗体项是编译器保护您的内容。可能无效的指针。
简单的修复方法是反转声明顺序,以便对cost_1
的所有引用都过时queue
:
let cost_1: NodeCost = NodeCost::new(1, 50, 0);
let cost_2: NodeCost = NodeCost::new(2, 30, 0);
let cost_3: NodeCost = NodeCost::new(3, 80, 0);
let mut queue: BinaryHeap<&NodeCost> = BinaryHeap::new();
这是一个有效的example on the playground
事件的顺序现在是:
cost_1
,cost_2
和cost_3
,其引用将插入BinaryHeap
。BinaryHeap
实例。BinaryHeap
。BinaryHeap
。引用可能会消失,因为它们引用的项目仍然有效。cost_3
。cost_2
。cost_1
。