【问题标题】:A "borrowed value does not live long enough" compiler error for serde Deserialize generic [duplicate]serde Deserialize generic [重复] 的“借用值不够长”编译器错误
【发布时间】:2021-12-11 03:35:46
【问题描述】:

为什么f1() 可以编译而f2() 不可以?

fn f1() {
    let s_json = "[]".to_string();
    for i in 0..10 {
        let ve: Vec<Rec1> = serde_json::from_str(&s_json).unwrap();
    }
}

fn f2<'a, T: Deserialize<'a>>() {
    let s_json = "[]".to_string();
    for i in 0..10 {
        let ve: Vec<T> = serde_json::from_str(&s_json).unwrap();
    }
}

这是编译器的输出:

| fn fff2<'a, T: Deserialize<'a>>() {
|         -- lifetime `'a` defined here
...
|         let ve: Vec<T> = serde_json::from_str(&s_json).unwrap();
|                          ---------------------^^^^^^^-
|                          |                    |
|                          |                    borrowed value does not live long enough
|                          argument requires that `s_json` is borrowed for `'a`
|     }
| }
| - `s_json` dropped here while still borrowed

我做错了什么?正确的f2() 签名是什么?

【问题讨论】:

  • 你不能写let s_json = "[]"; ... serde_json::from_str(s_json)吗?还是您的真实 JSON 值比文字“[]”更有趣?

标签: rust lifetime borrow-checker


【解决方案1】:

我找到了答案:DeserializeOwned 似乎只是为了这个目的而提供的——以避免一生的需要。 我想f2() 没有办法提供更短的生命周期,但f1() 不知何故没有这样的限制。

【讨论】:

  • f2 的生命周期较短的问题是,提供的'a 的生命周期必然比本地的s_json 的生命周期长,而当s_json 退出时会发生什么范围?反序列化对象的存储空间消失了!
  • 在我的示例中,我显然不需要这么长的生命周期,因为ve 会立即被删除(在每次循环迭代结束时)。但我想没有办法用标准的生命周期声明来声明它。
  • 啊,我知道你现在在哪里了。您希望此函数的用户能够指定 T 的类型,但在此函数本地的某个生命周期内使用它,而不是在函数外部。你把它写成T: for &lt;'a&gt; Deserialize&lt;'a&gt;,这恰好是你已经在使用的DeserializeOwned的同义词。
  • @rodrigo 谢谢!很有用! +1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-20
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 2015-10-18
  • 2017-03-11
  • 1970-01-01
相关资源
最近更新 更多