如何在Rust的装饰模式中使用生命周期说明符?

问题描述 投票:0回答:1

我是新生锈的,还没有生命周期特定的东西。为了将不同的问题分成不同的结构,我尝试做类似装饰模式的事情。但是,以下代码无法编译:

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
design-patterns rust decorator
1个回答
2
投票

忽略关于unsized类型的第一个错误,后两个错误都存在同样的问题:“无法移出借来的内容”

这个较小的示例触发相同的错误:

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);
}

有关更多信息,请参阅this answer,特别是关于所有权的部分或参见chapter four of the rust book

特别是你的问题,一个修复是改变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()
    }
}

// ...
© www.soinside.com 2019 - 2024. All rights reserved.