Rust错误:生命周期可能不够长,如何表达生命周期?

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

我有一个学习项目,正在构建分段的 WAL,并且正在为日志文件和整个 WAL(分段透明)实现 Stream https://github.com/danthegoodman1/WriteAhead/blob/1597d3357678fec402fe5b2fd3a6d4b0f5f53f3a/src/write_ahead.rs#L529-L556

目前,我遇到了编译器错误:

   Compiling writeahead v0.1.0 (/Users/dangoodman/code/WriteAhead)
warning: unused import: `TryStreamExt`
 --> src/write_ahead.rs:2:23
  |
2 | use futures::{Stream, TryStreamExt};
  |                       ^^^^^^^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

error: lifetime may not live long enough
   --> src/write_ahead.rs:515:28
    |
497 |   impl<'a, F: FileIO> WriteAheadStream<'a, F> {
    |        -- lifetime `'a` defined here
...
510 |       fn advance_to_next_stream(&mut self) -> Option<()> {
    |                                 - let's call the lifetime of this reference `'1`
...
515 |           let next_logfile = self
    |  ____________________________^
516 | |             .write_ahead
517 | |             .log_files
518 | |             .get_mut(&self.current_logfile_id)?;
    | |______________________________________________^ argument requires that `'1` must outlive `'a`

warning: `writeahead` (lib) generated 1 warning
error: could not compile `writeahead` (lib) due to 1 previous error; 1 warning emitted

这是有问题的代码的简化版本:

use std::collections::BTreeMap;

pub struct Logfile<F> {
    fio: F,
}

pub struct LogFileStream<'a, F> {
    logfile: &'a mut Logfile<F>,
}

impl<'a, F> LogFileStream<'a, F> {
    pub fn new(logfile: &'a mut Logfile<F>) -> Self {
        Self { logfile }
    }
}

pub struct WriteAhead<F> {
    log_files: BTreeMap<u64, Logfile<F>>,
}

pub struct WriteAheadStream<'a, F> {
    write_ahead: &'a mut WriteAhead<F>,
    current_logfile_id: u64,
    current_stream: Option<LogFileStream<'a, F>>,
}

impl<'a, F> WriteAheadStream<'a, F> {
    // Helper to get next stream when current one is exhausted
    fn advance_to_next_stream(&mut self) -> Option<()> {
        // If we have an active stream, drop it
        self.current_stream = None;

        // Try to get next logfile
        let next_logfile = self
            .write_ahead
            .log_files
            .get_mut(&self.current_logfile_id)?;

        // Create new stream
        self.current_stream = Some(LogFileStream::new(next_logfile));
        self.current_logfile_id += 1;
        Some(())
    }
}

我不确定如何表达这应该比它更长久。我期望 WriteAhead 将是单线程的,并拥有 Logfiles、LogFileStream 和 WriteAheadStreams 的生命周期。

也许我没有很好地表达所有权层次结构,但我不确定如何做到这一点。目标是 Axum 或其他网络服务之类的东西可以将其包装在 Arc> 中以利用它,但是想要在单个响应中流式传输 WAL 的响应可以使用 WriteAheadStream。

rust lifetime rust-tokio
1个回答
0
投票

我不确定你的做法是否明智,但让我严格评论一下这个问题。您的

fn advance_to_next_stream(&mut self) -> ...
采用
self
参数,其生命周期是任意的,并且它可能比
'a
短。 这使得任何
self.field
访问的生命周期也较短,即使
field
具有不同生命周期的引用类型。

但是,您可以要求

self
寿命足够长:

fn advance_to_next_stream(&'a mut self) -> Option<()>
                       // ^^^

现在您的代码符合要求。

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