使用带有生命周期说明符的函数时,借用的值不会存在足够长的时间
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
的数据中借用。”
- 反序列化的结果只在生命周期
'de
内有效。
- 反序列化采用必须在生命周期内存在的输入
'de
。
必须存在的输入不是reader
;它是读取的 字节。 您不能使用早于实际读取的字节的生命周期。
如果您尝试执行零拷贝反序列化,则必须将字节读入缓冲区并保留它们直到您完成值。
如果您只想要一个与您拥有的签名大致相同的函数,请使用 DeserializeOwned
而不是 Deserialize<'de>
— 这要求反序列化的值不能从输入中借用,因此它的生命周期是独立的输入的。
我对 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
的数据中借用。”
- 反序列化的结果只在生命周期
'de
内有效。 - 反序列化采用必须在生命周期内存在的输入
'de
。
必须存在的输入不是reader
;它是读取的 字节。 您不能使用早于实际读取的字节的生命周期。
如果您尝试执行零拷贝反序列化,则必须将字节读入缓冲区并保留它们直到您完成值。
如果您只想要一个与您拥有的签名大致相同的函数,请使用 DeserializeOwned
而不是 Deserialize<'de>
— 这要求反序列化的值不能从输入中借用,因此它的生命周期是独立的输入的。