尝试将具有生命周期的返回值设置为结构时,由于需求冲突,无法为 autoref 推断适当的生命周期

时间:2021-02-23 02:38:26

标签: rust lifetime


pub struct SumAggregator<'ctx> {
    input: i32,
    state: Cell<Option<IntValue<'ctx>>>,
}

impl<'ctx> SumAggregator<'ctx> {
    pub fn new() -> SumAggregator<'ctx> {
        SumAggregator {
            input: 0,
            state: Cell::new(None),
        }
    }
}

impl<'ctx> Aggregator for SumAggregator<'ctx> {
    fn init(&self, generator: &Generator, layout: &mut Layout, idx: i32) {
        let col_type = generator.context.i32_type();
        self.state.set(Some(col_type.const_int(0, true)));
        generator.build_debug("initialized state value:", self.state.get().unwrap().as_basic_value_enum());
    }

    fn process(&self, val: IntValue) {
        unimplemented!()
    }
}

以上是引发此错误的核心代码。 col_type.const_int(0, true) 可以返回具有 'ctx 生命周期的 IntValue。当我尝试将此值设置为我的结构时,发生了此错误。我是 Rust 的新手。据我所知,只有引用会导致生命周期问题。但是,在我的用例中,我只想放置一个值而不是对结构的引用(即使这个值有生命周期)。

这是错误堆栈:

error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
  --> src/operator/groupby/mod.rs:40:42
   |
40 |         let col_type = generator.context.i32_type();
   |                                          ^^^^^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #3 defined on the method body at 37:5...
  --> src/operator/groupby/mod.rs:37:5
   |
37 |     fn init(&self, generator: &Generator, layout: &mut Layout, idx: i32) {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...so that reference does not outlive borrowed content
  --> src/operator/groupby/mod.rs:40:24
   |
40 |         let col_type = generator.context.i32_type();
   |                        ^^^^^^^^^^^^^^^^^
note: but, the lifetime must be valid for the lifetime `'ctx` as defined on the impl at 36:6...
  --> src/operator/groupby/mod.rs:36:6
   |
36 | impl<'ctx> Aggregator for SumAggregator<'ctx> {
   |      ^^^^
note: ...so that the expression is assignable
  --> src/operator/groupby/mod.rs:41:24
   |
41 |         self.state.set(Some(col_type.const_int(0, true)));
   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = note: expected `Option<inkwell::values::IntValue<'ctx>>`
              found `Option<inkwell::values::IntValue<'_>>`

1 个答案:

答案 0 :(得分:0)

问题是 SumAggregator 想要一个 IntValue 的寿命至少与它本身一样长。但是在 init 函数中,您试图给它一个 IntValue,该 init 只存在到 IntValue 函数结束。

您可以通过指定 Generator 的引用的生命周期来确保 impl<'ctx> Aggregator for SumAggregator<'ctx> { fn init(&self, generator: &'ctx Generator, layout: &mut Layout, idx: i32) { // col_type is &'ctx IntType let col_type = generator.context.i32_type(); // int_value is &'ctx IntValue let int_value = col_type.const_int(0, true) // putting &'ctx IntValue into &'ctx IntValue self.state.set(Some(int_value)); generator.build_debug("initialized state value:", self.state.get().unwrap().as_basic_value_enum()); } ... } 的寿命足够长:

impl<'ctx> Aggregator for SumAggregator<'ctx> {
    fn init<'a, 'b>(&self, generator: &'a Generator, layout: &'b mut Layout, idx: i32) {
        // col_type is &'a IntType
        let col_type = generator.context.i32_type();

        // int_value is &'a IntValue
        let int_value = col_type.const_int(0, true)

        // trying to put &'a IntValue into &'ctx IntValue
        self.state.set(Some(int_value));

        generator.build_debug("initialized state value:", self.state.get().unwrap().as_basic_value_enum());
    }

    ...
}

如果不这样做,则等同于:

//Bitmap bmp = ThumbnailUtils.createVideoThumbnail(data, MediaStore.Video.Thumbnails.MINI_KIND);
 //videoModel.setVideoThumb(bmp);