2017-04-17 51 views
1

我一直試圖在Rust中創建一個簡單的解釋器。這是一段代碼片段。從矢量返回元素時出錯E0495

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()) 
    |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 

我缺少什麼?

回答

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]),它取消參考BoxData,然後重新引用它。因爲您的實現不符合規則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) 
+0

感謝您的回答!但如果我理解正確,[這是行不通的:/](https://play.rust-lang.org/?gist=2dc89d594443628eb548d5e75e1fcfc3&version=stable&backtrace=0) – Abogical

+0

@Abogical你需要[改變特質定義和實施](https://play.integer32.com/?gist=d619b6bbc9a32a0755cc4aa7f80cdbe3&version=stable);我在答案中澄清了這一點。 – Shepmaster

+0

噢,是的,對於愚蠢的錯誤感到抱歉,謝謝! – Abogical