使用带有生命周期说明符的函数时,借用的值不会存在足够长的时间

Borrowed value does not live long enough when using functions with lifetime specifier

我对 Rust 的生命周期相当陌生。这是我写的代码:

pub fn from_reader<'de, T, R>(reader: &'de mut R) -> Result<T>
where
    T: Deserialize<'de>,
    R: Read,
{
    let mut reader = BufReader::new(reader);
    from_buf_reader(&mut reader)
}

pub fn from_buf_reader<'de, T, R>(reader: &'de mut R) -> Result<T>
where
    T: Deserialize<'de>,
    R: BufRead,
{
    //...
}

我收到以下错误:

error[E0597]: `reader` does not live long enough
  --> src/de.rs:34:21
   |
28 | pub fn from_reader<'de, T, R>(reader: &'de mut R) -> Result<T>
   |                    --- lifetime `'de` defined here
...
34 |     from_buf_reader(&mut reader)
   |     ----------------^^^^^^^^^^^-
   |     |               |
   |     |               borrowed value does not live long enough
   |     argument requires that `reader` is borrowed for `'de`
35 | }
   | - `reader` dropped here while still borrowed

根据我的理解,新创建的 reader 需要有 'de 的生命周期,这是不可能的,因为 'de 在这个函数被调用之前就开始了。这是正确的解释吗?

有没有办法在不直接获取参数所有权的情况下解决这个问题?

作为一般原则,几乎总是错误 将相同的生命周期参数用于 &mut 引用作为其他任何东西。这是因为可变引用的生命周期是 不变的: 与不可变引用不同,你不能用比它短 的生命周期来标记它原始借用的实际生命周期(因为这会干扰验证可变借用与任何其他借用没有重叠)。

但是,您不需要该原则,因为这里有一个更直接的问题:

在 Serde 中,Deserialize<'de> 表示“反序列化为一个结构,该结构 从生命周期为 'de 的数据中借用。

  1. 反序列化的结果只在生命周期'de内有效。
  2. 反序列化采用必须在生命周期内存在的输入 'de

必须存在的输入不是reader;它是读取的 字节。 您不能使用早于实际读取的字节的生命周期。

如果您尝试执行零拷贝反序列化,则必须将字节读入缓冲区并保留它们直到您完成值。

如果您只想要一个与您拥有的签名大致相同的函数,请使用 DeserializeOwned 而不是 Deserialize<'de> — 这要求反序列化的值不能从输入中借用,因此它的生命周期是独立的输入的。