#Help with lifetimes

10 messages · Page 1 of 1 (latest)

true wharf
#

I have been messing around with deserialization and am trying to get zero-copy deserialization working in my app. Playing around in a small toy main() method I was able to get it working, but when I try to use it in something a bit more real, the compiler yells at me. This is what my deserialize function looks like:

pub fn deserialize<'de, T>(buff: &'de [u8]) -> T
where
    T: Deserialize<'de> + DeserializeOwned,
{
    let mut de = Deserializer::from_read_ref(buff);
    Deserialize::deserialize(&mut de).expect("Unable to deserialize!")
}

And this is the function that calls it (slimmed down)

pub async fn get<'de, T>(&mut self, key: String) -> T
where
    T: Deserialize<'de>,
{
    .
    .
    .
    let buff = receiver.await.expect("Receiver Error!").payload;
    deserialize(&buff)
}

I thought that the buffer was living long enough, but the compiler says that it is being dropped at the closing bracket while still being borrowed. Does it have something to do with my function being async?

fresh oyster
#

by writing fn get<'de, ... you are proposing that the caller of the function get gets to choose the deserialization lifetime

#

but this is false because the buffer is in buff which is a local variable

#

when you want to do deserialization that borrows from a buffer, you must store that buffer somewhere and then deserialize it and use it while the buffer still exists

#

you're trying to return the value while dropping the buffer

#
    let buff = ....payload;    // this is a local variable
    deserialize(&buff)         // this references into it
}                              // and it is dropped now
true wharf
#

I must be misunderstanding the order of things then. I thought that deserialize() would be called, terminate, then return the value and drop the buffer. What is actually occurring?

#

I changed the function signature to this and the compiler is ok with it, but i'm not sure if I am actually fixing things or not:

    pub async fn get<T>(&mut self, key: String) -> T
    where
        T: for<'a> Deserialize<'a>,
    {
true wharf
#

Ok, I feel a little sheepish. I was unaware that the buffer had to live as long as the deserialized object. I was incorrectly assuming that ownership of the bytes was transferred to the new object. This makes a lot more sense now.

fresh oyster
#

It is possible for the bytes to transferred over, but that will involve some copying, so “zero-copy” means not doing that