【问题标题】:Trouble with Rust Lifetime in Generic function [duplicate]通用函数中的 Rust Lifetime 问题[重复]
【发布时间】:2020-05-24 15:37:55
【问题描述】:

我有一个简单的函数,我想在 rust 中进行通用化。我遇到了一生的错误。我仍然了解生锈的终生一面。

该函数只是使用 serde 的序列化将 1 个结构转换为另一个。

这里有一个rust playground 完整的简单场景。

代码:

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[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

我尝试了几种有生命周期和没有生命周期的方法。我尝试添加块以查看是否会在没有运气的情况下改变事情。

对我做错了什么有什么想法吗?

编辑: - 添加了完整的编译器错误输出

【问题讨论】:

  • 错误信息不仅仅是“借来的价值不够长”。它包含更多信息,解释了为什么借用检查器认为借用的时间超过了它借用的价值。我建议仔细阅读这些信息——它可以帮助你。如果您仍然不明白问题所在,请提供完整示例,以便我们重现错误,或者至少在您的帖子中包含完整的错误消息。
  • 我编辑了这个以显示完整的编译器输出。我在问题中链接的 rust 操场上有完整的代码。我不想在这里全部添加,因为我认为这会增加混乱。
  • 感谢编辑,太完美了!

标签: rust


【解决方案1】:

对于编译器来说,生命周期参数总是表示严格比函数调用长的生命周期。但是,在这里您尝试使用局部变量并声称它具有生命周期 'de,这是不可能的,因为它是局部变量,因此它的生命周期比函数调用短。

为了将特征中的生命周期参数与局部变量混合,我们必须使用higher-rank trait bounds。我们希望 T每个 生命周期 'de 实现 Deserialize&lt;'de&gt;(而不仅仅是调用者选择的一个特定生命周期)。是这样写的(注意我们现在可以省略 'a 生命周期):

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

【讨论】:

  • 太棒了!谢谢!!!看起来我现在需要研究“for”部分,但这解决了问题。再次感谢!
猜你喜欢
  • 1970-01-01
  • 2021-07-11
  • 2016-11-14
  • 1970-01-01
  • 2021-08-28
  • 1970-01-01
  • 1970-01-01
  • 2014-08-15
  • 2022-11-03
相关资源
最近更新 更多