Как использовать спецификатор времени жизни в шаблоне декоратора в Rust? - PullRequest
0 голосов
/ 20 февраля 2019

Я новичок в ржавчине и еще не получил информацию о сроке службы.Чтобы разделить разные задачи на разные структуры, я пытаюсь сделать что-то похожее на шаблон декоратора.Однако следующий код не компилируется:

trait T {
    fn foo(self) -> u64;
}

struct Inner {}

impl T for Inner {
    fn foo(self) -> u64 {
        42
    }
}

struct Outer<'a> {
    delegate: &'a T,
}

impl<'a> T for Outer<'a> {
    fn foo(self) -> u64 {
        self.delegate.foo()
    }
}

pub fn dec_test() {
    let inner = &Inner {};
    let outer = Outer{delegate:inner};

    println!("Meaning of life: {}", outer.foo());
}

Я получаю следующую ошибку

error[E0161]: cannot move a value of type dyn T: the size of dyn T cannot be statically determined
  --> src/lib.rs:19:9
   |
19 |         self.delegate.foo()
   |         ^^^^^^^^^^^^^

error[E0507]: cannot move out of borrowed content
  --> src/lib.rs:19:9
   |
19 |         self.delegate.foo()
   |         ^^^^^^^^^^^^^ cannot move out of borrowed content

error: aborting due to 2 previous errors

1 Ответ

0 голосов
/ 20 февраля 2019

Игнорирование первой ошибки о типах без размера, обе вторые две ошибки относятся к одной и той же проблеме: «невозможно удалить из заимствованного содержимого» * ​​1001 *

Этот меньший пример вызывает ту же ошибку:

struct Inner {}

impl Inner {
    // consumes self. requires ownership
    fn foo(self) -> u64 {
        42
    }
}

fn main() {
    let my_inner = Inner {};
    let borrow = &my_inner;
    let answer = borrow.foo(); // oops! we are using a borrowed version that we don't own
    println!("meaning of life {}", answer);
}

Для получения дополнительной информации см. этот ответ , в частности, часть о владении, или см. четвертую главу книги о ржавчине .

Специально для вашей проблемы одно решениеизменить trait T так, чтобы он заимствовал только свой аргумент:

trait T {
    fn foo(&self) -> u64; // notice the change: `self` -> `&self`
}

// ...

impl T for Inner {
    fn foo(&self) -> u64 { // notice the change: `self` -> `&self`
        42
    }
}

// ...

impl<'a> T for Outer<'a> {
    fn foo(&self) -> u64 { // notice the change: `self` -> `&self`
        self.delegate.foo()
    }
}

// ...
...