反序列化通用结构上的特征绑定

Deserialize trait bound on generic struct

我想通过 serde_json 为通用结构构建一个解析器,这是简化的逻辑。它会产生一个错误:“src 的寿命不够长”。

但为什么这会导致生命周期不够长的错误?

有什么办法可以解决吗,或者根本不建议这样写代码?

use serde_json;
use serde::Deserialize;
use std::marker::PhantomData;

#[derive(Default)]
struct Parser<'de, P:Deserialize<'de>>{
    phantom1: PhantomData<&'de ()>,
    phantom2: PhantomData<P>,
}

impl<'de, P:Deserialize<'de>> Parser<'de,P>{
    fn parse(&self, src:&'de String){
        serde_json::from_str::<P>(&src).unwrap();
    }
}

#[derive(Default)]
struct OutterParser<'de, P:Deserialize<'de>>{
    parser: Parser<'de, P>
}

impl<'de, P:Deserialize<'de>> OutterParser<'de,P>{
  fn read_and_parse(&self){
    let src = String::from(r#""""#);
    self.parser.parse(&src); 
  }
}

fn main(){
    let parser = OutterParser::<String>::default();
    parser.read_and_parse();
}

这是rust playground link


编辑: 感谢凯文的回答。我曾经以为'de lifetime会在本地parse函数中自动导出为lifetime。从本地 &src 构建 P 结构后,可以删除 src

现在我知道如果没有明显的注释,函数参数的生命周期将小于 'de

但是如果函数签名修改为fn parse(&self, &'de str)'de会进一步向上传播,这不是我想要的。

P: Deserialize<'de> 表示反序列化为 P 类型的值需要输入数据,该数据必须至少存在 'de.

    fn parse(&self, src:String){
        serde_json::from_str::<P>(&src).unwrap();

相反,您提供了对局部变量 src 的引用,该变量将在 parse 函数的末尾删除,因此肯定 更短 'de.

为了不出现这个问题,您必须定义 parse 使其接受对 'de:[=20 有效的 reference =]

    fn parse(&self, src: &'de str) {

在另一个问题中找到答案:)

更简单的解决方法是使用 DeserializeOwned...

use serde_json;
use serde::de::DeserializeOwned;
use std::marker::PhantomData;

#[derive(Default)]
struct Parser<P:DeserializeOwned>{
    phantom2: PhantomData<P>,
}

impl<P:DeserializeOwned> Parser<P>{
    fn parse(&self, src:&String){
        serde_json::from_str::<P>(&src).unwrap();
    }
}

#[derive(Default)]
struct OutterParser<P:DeserializeOwned>{
    parser: Parser<P>
}

impl<P:DeserializeOwned> OutterParser<P>{
  fn read_and_parse(&self){
    let src = String::from(r#""""#);
    self.parser.parse(&src); 
  }
}

fn main(){
    let parser = OutterParser::<String>::default();
    parser.read_and_parse();
}