Trouble with Rust Lifetime in Generic function [duplicate]

拥有回忆 提交于 2020-06-16 11:09:10

问题


I have a simple function that I want to make generic, in rust. I am getting a lifetime error. I am still getting the hang of the lifetime side of rust.

The function simply converts 1 struct into another using serde's serialization.

Here is a a rust playground with the full simple scenario.

Code:

pub fn convert<'de: 'a, 'a, T>(from: &'a Left, print: bool) -> (T, &'a Left)
where
    T: Deserialize<'de> + std::fmt::Debug {

    let serialized = serde_json::to_string(&from);
    let serialized = serialized.unwrap();
    let deserialized: T;
    {
    let deserialized_raw = serde_json::from_str(&serialized);
    deserialized = deserialized_raw.unwrap();
    }
    if print {
        println!("-------------A-----------------------------------");
        println!("serialized = {}", &serialized);
        println!("--------------B----------------------------------");
        println!("deserialized = {:?}", deserialized);
        println!("--------------C----------------------------------");
    };
    (deserialized, from)
}

Error:

error[E0597]: `serialized` does not live long enough
  --> src/main.rs:38:49
   |
30 | pub fn convert<'de: 'a, 'a, T>(from: &'a Left, print: bool) -> (T, &'a Left)
   |                --- lifetime `'de` defined here
...
38 |     let deserialized_raw = serde_json::from_str(&serialized);
   |                            ---------------------^^^^^^^^^^^-
   |                            |                    |
   |                            |                    borrowed value does not live long enough
   |                            argument requires that `serialized` is borrowed for `'de`
...
49 | }
   | - `serialized` dropped here while still borrowed

I tried this a few ways with and without lifetimes. I tried adding blocks to see if that changes things with no luck.

Any thoughts on what I am doing wrong?

Edited: - Added the full compiler error output


回答1:


To the compiler, lifetime parameters always represent lifetimes that live strictly longer than the function call. However, here you're trying to use a local variable and claim it has lifetime 'de, which is impossible because it's a local variable, thus it has a lifetime shorter than the function call.

In order to mix lifetime parameters in traits with local variables, we must use higher-rank trait bounds. We want T to implement Deserialize<'de> for every lifetime 'de (not just one specific lifetime chosen by the caller). This is written like this (note that we can now elide the 'a lifetime):

pub fn convert<T>(from: &Left, print: bool) -> (T, &Left)
where
    T: for<'de> Deserialize<'de> + std::fmt::Debug
{
    // no changes here
}


来源:https://stackoverflow.com/questions/60131425/trouble-with-rust-lifetime-in-generic-function

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!