代码之家  ›  专栏  ›  技术社区  ›  fyaa

如何为创建具有特征生命周期边界的对象的生产者找到通用边界

  •  0
  • fyaa  · 技术社区  · 4 年前

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

    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 接收生产商 一些东西 具有该特性 借款人<'b> 然而,由于我无法阻止在 执行 函数认为所有生成的项必须在整个函数执行过程中存活。实际上,它们只是实现的静态对象 借款人<'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
    

    也许你可以帮我。

    0 回复  |  直到 4 年前
        1
  •  2
  •   vallentin Remi    4 年前

    这可以通过以下方式解决 higher-rank trait bounds :

    你不必在这里度过一生。相反,你需要定义一个忙碌的一生 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);
        }
    }
    

    Playground

    这里很好地解释了更高等级的特征边界:
    How does for<> syntax differ from a regular lifetime bound?