2014-11-16 3 views
2

У меня есть черта, которая указывает время жизни на метод trait, и у меня есть структура, которая содержит значение, которое также требует жизни. Я хотел бы, чтобы структура реализовала черту, а это значит, что время жизни должно совпадать. Однако я не знаю, как это выразить.Как я могу объединить времена жизни между структурой и признаком?

struct Context<'d> { 
    name: &'d str, 
} 

struct Value<'d> { 
    name: &'d str, 
} 

trait Expression { 
    fn evaluate<'d>(&self, context: &Context<'d>) -> Value<'d>; 
} 

struct Constant<'d> { 
    value: Value<'d>, 
} 

Покушение 1 - с указанием срока службы по методу:

impl<'d> Expression for Constant<'d> { 
    fn evaluate<'d>(&self, _unused: &Context<'d>) -> Value<'d> { 
     self.value 
    } 
} 

Это приводит к тому, продолжительность жизни на impl быть слежка, и я получаю ошибки как:

$ rustc x.rs 
x.rs:18:5: 20:6 help: consider using an explicit lifetime parameter as shown: fn evaluate<'d>(&self, _unused: &Context<'d>) -> Value<'d> 
x.rs:18  fn evaluate<'d>(&self, _unused: &Context<'d>) -> Value<'d> { 
x.rs:19   self.value 
x.rs:20  } 
x.rs:19:9: 19:19 error: mismatched types: expected `Value<'d>`, found `Value<'d>` (lifetime mismatch) 
x.rs:19   self.value 
       ^~~~~~~~~~ 

Попытка 2 - не указывая цели на всю жизнь:

impl<'d> Expression for Constant<'d> { 
    fn evaluate(&self, _unused: &Context<'d>) -> Value<'d> { 
     self.value 
    } 
} 

Это заставляет меня на самом деле не реализовать метод:

$ rustc x.rs 
x.rs:18:5: 20:6 error: method `evaluate` has an incompatible type for trait: expected concrete lifetime, found bound lifetime parameter 'd [E0053] 
x.rs:18  fn evaluate(&self, _unused: &Context<'d>) -> Value<'d> { 
x.rs:19   self.value 
x.rs:20  } 
x.rs:18:60: 20:6 note: expected concrete lifetime is the lifetime 'd as defined on the block at 18:59 
x.rs:18  fn evaluate(&self, _unused: &Context<'d>) -> Value<'d> { 
x.rs:19   self.value 
x.rs:20  } 

ответ

3

Вам нужно дать самой черте параметра пожизненный:

trait Expression<'d> { 
    fn evaluate(&self, context: &Context<'d>) -> Value<'d>; 
} 

impl<'d> Expression<'d> for Constant<'d> { 
    fn evaluate(&self, _unused: &Context<'d>) -> Value<'d> { 
     self.value 
    } 
} 

Playpen

Причина вы получаете сообщение об ошибке №1 (кроме теневого), что ваша черта ограничивает context, чтобы иметь время жизни e тип возврата, но не self. Чтобы ограничить self, вам нужно иметь параметр lifetime на самом признаке.

Причина, по которой вы получаете ошибку # 2, проста: времена жизни являются частью системы типов и не могут не соответствовать. Любой общий код, который вы пишете, должен работать для всех исполнителей этого признака - и если сроки жизни связаны друг с другом в каждой реализации, это не сработает.

+0

Спасибо, я сделаю это. Я действительно надеялся, что это не так, поскольку это означает, что мне нужно изменить 100 строк кода, чтобы отслеживать эту жизнь сейчас ... – Shepmaster

+0

@Shepmaster да, в Rust вам придется часто отслеживать жизни, если вы хотите избегайте копирования. – Manishearth

Смежные вопросы