1

我已将我的实际代码简化为这个最小的示例:

trait Producer<P> where P: Something {
    fn produce(&self) -> Box<P>;
}

struct P1 {}

impl Producer<B1> for P1 {
    fn produce(&self) -> Box<B1> {
        Box::new(B1 {})
    }
}

trait Something {}

trait Borrower<'b> {
    type B: std::fmt::Display;
    
    fn borrow(&'b self) -> Self::B;
}

struct B1 {}

impl Something for B1 {}

impl<'b> Borrower<'b> for B1 {
    type B = Borrowing1<'b>;
    
    fn borrow(&'b self) -> Self::B {
        Borrowing1 { _b: &self }
    }
}

struct Borrowing1<'b> {
    _b: &'b B1,
}

impl<'b> std::fmt::Display for Borrowing1<'b> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "Borrowing1")
    }
}

fn perform<'b, P, B>(producer: P) where P: Producer<B>, B: Something + Borrower<'b> + 'static {
    for _ in 0..1 {
        let b = producer.produce();
        let s = b.borrow().to_string();
        eprintln!("{}", s);
    }
}

fn main() {
   let p1 = P1 {};
   perform(p1);
}

我有一种Producer创建Something. 并且可以实现的东西Borrower<'b>,它引入了生命周期。然后,我想限制一个函数perform来接收Something具有 trait 的生产者Borrower<'b>。但是,由于我无法阻止在perform函数中引入生命周期,因此我认为所有生成的项目都必须为整个函数执行而存在。实际上,它们只是实现的静态对象Borrower<'b>。但我很难找到正确的界限。

错误消息反映:

error[E0597]: `*b` does not live long enough
  --> src/main.rs:46:17
   |
43 | fn perform<'b, P, B>(producer: P) where P: Producer<B>, B: Something + Borrower<'b> + 'static {
   |            -- lifetime `'b` defined here
...
46 |         let s = b.borrow().to_string();
   |                 ^---------
   |                 |
   |                 borrowed value does not live long enough
   |                 argument requires that `*b` is borrowed for `'b`
47 |         eprintln!("{}", s);
48 |     }
   |     - `*b` dropped here while still borrowed

也许你可以帮助我。

4

1 回答 1

2

这可以使用更高等级的特征界限来解决:

您不必经过一生才能在这里发挥作用。相反,您需要在borrow()调用时定义一个生命周期。以下应该可以解决问题:

fn perform<P, B>(producer: P)
where
    P: Producer<B>,
    for<'b> B: Something + Borrower<'b> + 'static,
{
    for _ in 0..1 {
        let b = producer.produce();
        let u = b.borrow();
        let s = u.to_string();
        eprintln!("{}", s);
    }
}

操场

较高等级的特征界限在这里得到了很好的解释:
for<> 语法与常规生命周期界限有何不同?

于 2020-12-14T00:12:40.913 回答