从向量

时间:2017-04-17 15:49:59

标签: vector rust lifetime

我一直在尝试在Rust中创建一个简单的解释器。这是一段代码片段。

use std::vec::Vec;
use std::option::Option;
use std::borrow::Borrow;

trait Data {}

trait Instruction {
    fn run(&self, stack: &mut Vec<Box<Data>>) -> Option<&Data>;
}

struct Get {
    stack_index: usize,
}

impl Instruction for Get {
    fn run(&self, stack: &mut Vec<Box<Data>>) -> Option<&Data> {
        Some(stack[self.stack_index].borrow())
    }
}

fn main() {}

上面包含一条简单的Get指令。它有一个run方法,它只返回给定堆栈Data中的值。 Data是一个抽象的特征,实际上代表任何类型的数据。我还没有实现Data

但是,编译代码会生成错误代码E0495

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
  --> <anon>:17:14
   |
17 |         Some(stack[self.stack_index].borrow())
   |              ^^^^^^^^^^^^^^^^^^^^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the body at 16:63...
  --> <anon>:16:64
   |
16 |       fn run(&self, stack: &mut Vec<Box<Data>>) -> Option<&Data> {
   |  ________________________________________________________________^ starting here...
17 | |         Some(stack[self.stack_index].borrow())
18 | |     }
   | |_____^ ...ending here
note: ...so that reference does not outlive borrowed content
  --> <anon>:17:14
   |
17 |         Some(stack[self.stack_index].borrow())
   |              ^^^^^
note: but, the lifetime must be valid for the anonymous lifetime #1 defined on the body at 16:63...
  --> <anon>:16:64
   |
16 |       fn run(&self, stack: &mut Vec<Box<Data>>) -> Option<&Data> {
   |  ________________________________________________________________^ starting here...
17 | |         Some(stack[self.stack_index].borrow())
18 | |     }
   | |_____^ ...ending here
note: ...so that expression is assignable (expected std::option::Option<&Data>, found std::option::Option<&Data>)
  --> <anon>:17:9
   |
17 |         Some(stack[self.stack_index].borrow())
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

我错过了什么?

1 个答案:

答案 0 :(得分:3)

What is the return type of the indexing operation on a slice?中所述,stack[self.stack_index]将返回值中的值。然后,您尝试返回对局部变量的引用,这是Is there any way to return a reference to a variable created in a function?中所述的不允许的。

实际上,您需要执行Some(&*stack[self.stack_index]),它会取消引用Box以获取Data,然后重新引用它。由于您的实现不符合lifetime elision的规则,因此您需要为特征方法和实现添加显式生命周期:

fn run<'a>(&self, stack: &'a mut Vec<Box<Data>>) -> Option<&'a Data>

我可能会使用getmap来实现它:

stack.get(self.stack_index).map(Box::as_ref)