使用“从特征”绑定时,引用的生命周期超过借用的内容

时间:2018-12-04 18:31:58

标签: generics rust traits lifetime

我有以下代码:

pub trait BlockFactory<B, T> {
    fn build_block(template: &BlockTemplate<T>, nonce: u32, previous_nonce: u32) -> B;
}

pub struct BlockTemplate<T> {
    number: u32,
    previous_hash: String,
    transactions: Vec<T>,
}

impl<T> BlockTemplate<T> {
    pub fn new(number: u32, previous_hash: String, transactions: Vec<T>) -> BlockTemplate<T> {
        BlockTemplate {
            number,
            previous_hash,
            transactions,
        }
    }
}

pub struct DefaultBlockFactory {}

impl<'a, B, T> BlockFactory<B, T> for DefaultBlockFactory
where
    B: From<&'a BlockTemplate<T>>,
    T: 'a,
{
    fn build_block(template: &BlockTemplate<T>, nonce: u32, previous_nonce: u32) -> B {
        B::from(template)
    }
}

BlockFactory的实现者应该引用BlockTemplate并基于它返回一个Block

默认实现应适用于任何类型的B和任何类型的T,前提是可以从B构建BlockTemplate<T>

当我尝试编译它时,出现以下错误:

error[E0312]: lifetime of reference outlives lifetime of borrowed content...
  --> src/lib.rs:29:17
   |
29 |         B::from(template)
   |                 ^^^^^^^^
   |
note: ...the reference is valid for the lifetime 'a as defined on the impl at 23:6...
  --> src/lib.rs:23:6
   |
23 | impl<'a, B, T> BlockFactory<B, T> for DefaultBlockFactory
   |      ^^
note: ...but the borrowed content is only valid for the anonymous lifetime #1 defined on the method body at 28:5
  --> src/lib.rs:28:5
   |
28 | /     fn build_block(template: &BlockTemplate<T>, nonce: u32, previous_nonce: u32) -> B {
29 | |         B::from(template)
30 | |     }
   | |_____^

当我通过'a方法为template指定生存期build_block时:

pub trait BlockFactory<'a, B, T> {
    fn build_block(template: &'a BlockTemplate<T>, nonce: u32, previous_nonce: u32) -> B;
}

// clip

impl<'a, B, T> BlockFactory<'a, B, T> for DefaultBlockFactory
where
    B: From<&'a BlockTemplate<T>>,
    T: 'a,
{
    fn build_block(template: &'a BlockTemplate<T>, nonce: u32, previous_nonce: u32) -> B {
        B::from(template)
    }
}

fn example_build<'b, B, T>(template: BlockTemplate<T>)
where
    B: From<&'b BlockTemplate<T>>,
    T: 'b,
{
    let block: B = DefaultBlockFactory::build_block(&template, 0, 0);
}

调用时出现编译器错误

error[E0597]: `template` does not live long enough
  --> src/lib.rs:28:54
   |
28 |     let block: B = DefaultBlockFactory::build_block(&template, 0, 0);
   |                                                      ^^^^^^^^ borrowed value does not live long enough
29 | }
   | - borrowed value only lives until here
   |
note: borrowed value must be valid for the lifetime 'b as defined on the function body at 23:18...
  --> src/lib.rs:23:18
   |
23 | fn example_build<'b, B, T>(template: BlockTemplate<T>)
   |                  ^^

似乎由于某种原因,'a被推断为'static,但我不知道为什么。

0 个答案:

没有答案