2016-09-15 13 views
0

Я пытаюсь использовать builder pattern в Rust, однако я получаю ошибку компиляции.Невозможно скомпилировать шаблон построителя Rust, потому что заемное значение не достаточно долгое время

pub struct DynamicParams { 
    port: Option<u16>, 
} 

impl DynamicParams { 
    pub fn new() -> Self { 
     DynamicParams { port: None } 
    } 

    pub fn port(&mut self, port: u16) -> &mut Self { 
     self.port = Some(port); 
     self 
    } 
} 

fn main() { 
    let params = DynamicParams::new().port(1); 
} 

Это available on play.rust-lang.org.

Ошибка:

error: borrowed value does not live long enough 
    --> <anon>:17:18 
    |> 
17 |>  let params = DynamicParams::new().port(1); 
    |>     ^^^^^^^^^^^^^^^^^^^^ does not live long enough 
note: reference must be valid for the block suffix following statement 0 at 17:46... 
    --> <anon>:17:47 
    |> 
17 |>  let params = DynamicParams::new().port(1); 
    |>            ^
note: ...but borrowed value is only valid for the statement at 17:4 
    --> <anon>:17:5 
    |> 
17 |>  let params = DynamicParams::new().port(1); 
    |>  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
help: consider using a `let` binding to increase its lifetime 
    --> <anon>:17:5 
    |> 
17 |>  let params = DynamicParams::new().port(1); 
    |>  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 

error: aborting due to previous error 

Однако насколько я могу видеть, что это очень похоже на builder pattern, as described in the Rust book. Что происходит? Что я делаю не так?

Я использую Rust 1.11.

ответ

2

Вы, кажется, отсутствует метод окончательной доработке возвращающий принадлежащего объект, как:

pub fn finalize(&self) -> DynamicParams { 
    DynamicParams { port: self.port } 
} 

Когда у вас есть вы можете сделать следующее:

let params = DynamicParams::new().port(1).finalize(); 

Который работает, потому что с правой стороны выражение не возвращает ссылку, а принадлежит объекту. port() возвращает только изменяемую ссылку; объект, созданный new(), должен быть введен с помощью более раннего связывания let, чтобы ссылка на него была действительной.

+0

Спасибо! Я изменил методы getter для работы с собственными объектами и вернул их. Не ссылки. Тогда мне не нужен '.finalize()' – Rory