拥有的变量似乎不会发出与 serde 反序列化生命周期所需的一样长的借用

Owned variable seems to not issue a borrow that lives as long as required by a serde deserialize lifetime

我正在尝试编写一个特征,允许对任意(反)序列化结构进行 gzip encode/decode。我的主要用例是通过干净的 API 在磁盘上保留一些有状态的结构。为此,任何时候结构 S 实现 serdeSerializeDeserialize,并且我们的特征在范围内,它的 gzipped + 序列化副本应该是 read/written by/to 任何按需 Read/Write

例如:

描述某些(反)序列化结构的 reading/writing 的 API 的特征。

use flate2::read::GzDecoder;
use flate2::write::GzEncoder;
use serde::{Serialize, Deserialize};
use rmp_serde::{Serializer};
use std::io::{Read, Write};

pub type Result<T, E = std::io::Error> = std::result::Result<T, E>;

pub trait ReadWriteState<S: Serialize + Deserialize> {
    /// Write the given persistent state to a stream.
    fn write_state(&mut self, state: &S) -> Result<usize>;
    /// Write the given persistent state to a stream.
    fn read_state(&mut self) -> Result<S>;
}

用于(反)可序列化状态的 ReadWriteState 的一揽子实现,同时通过任何 std::io::Readstd::io::Write

impl<S, T> ReadWriteState<S> for T 
where
    S: Serialize + Deserialize, // This doesn't work because of lifetimes in serde Deserializer.
    T: Read + Write
{
    /// Serialize the state into messagepack and then
    /// GzEncode it before sending to the output stream.
    fn write_state(&mut self, state: &S) -> Result<usize> {
        let mut buf = Vec::new();
        state
            .serialize(&mut Serializer::new(&mut buf))
            .unwrap_or_else(|_| panic!("Could not serialize data."));

        let mut e = GzEncoder::new(Vec::new(), Compression::default());
        e.write_all(&buf)?;

        let compressed_bytes = e.finish()?;
        let length = compressed_bytes.len();

        self.write_all(&compressed_bytes)?;
    }

    /// Decode the gzipped stream into msgpack and then further deserialize it into the generic state struct.
    fn read_state(&mut self) -> Result<S, serde_json::Error> {
        let mut decoder = GzDecoder::new(self);
        let mut buf = Vec::new(); // The buf is created here so it is owned by this function scope.
        decoder.read_to_end(&mut buf).expect("Couldn't read the gzipped stream to end.");
        serde_json::from_slice::<'de, S>(&buf) // (*)

        // This is what I expect should work fine 
        // but the borrow checker complains that 
        // `buf` doesn't live long enough.
    }

}

可由 serde_derive 宏(反)序列化的示例有状态结构。

// Now suppose we have some struct that is Serialize as
// well as Deserialize.

#[derive(Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct FooMap<K, V> 
where
    // For a moment, suppose Deserialize doesn't need a lifetime.
    // To compile, it should look more like Deserialize<'a> for some defined
    // lifetime 'a, but let's ignore that for a moment.
    K: Clone + Hash + Eq + Serialize + Deserialize,
    V: Eq + Serialize + Deserialize
{
    pub key: K,
    pub value: V
}

方便的磁盘持久化 API 为我们的 FooMap 在行动。

// Now I should be able to write gzipped + messagepacked FooMap to file.

pub fn main() {
    let foomap = FooMap {
        key: "color",
        value: "blue"
    };
    let mut file = std::fs::File::create("/tmp/foomap.gz").expect("Could not create file.");
    let bytes_written = file.write_state(&foomap).expect("Could not write state.");
    println!("{} bytes written to /tmp/foomap.gz", bytes_written);

    let mut file = std::fs::File::open("/tmp/foomap.gz").expect("Could not open file.");
    let recovered: FooMap<&str, &str> = file.read_state().expect("Could not recover FooMap.");
    assert_eq!(foomap, recovered);
}

您可能会注意到上面的代码存在一些问题。我知道的一个是 Deserialize 用作特征绑定时缺少生命周期注释。 Serde 有一个关于反序列化器生命周期的beautiful write up

我整理了一个 Playground 试图解决生命周期问题,这样做时,我遇到了另一个编译器错误 (*),鉴于此,我觉得这很奇怪情况。

我真的很困惑,我到底是在什么时候走错了路,又该如何改正。如果有人能帮助我理解我在此实现中所犯的错误以及如何防止它再次发生,我将不胜感激。

如果您使用 DeserializeOwned 而不是 Deserialize<'de> 作为绑定,您的代码将编译。

serde's lifetime pageDeserializeOwned 有这样的说法(我的重点):

This means "T can be deserialized from any lifetime." The callee gets to decide what lifetime. Usually this is because the data that is being deserialized from is going to be thrown away before the function returns, so T must not be allowed to borrow from it. For example a function that accepts base64-encoded data as input, decodes it from base64, deserializes a value of type T, then throws away the result of base64 decoding. [...]

这完全符合您的用例,因为 buf 在函数 returns 之前被删除。