gpt4 book ai didi

generics - 限制 Rust 结构体的泛型参数进行反序列化

转载 作者:行者123 更新时间:2023-12-02 20:22:28 28 4
gpt4 key购买 nike

我想限制可(反)序列化的结构具有也可反序列化的通用参数。派生宏Deserialize不需要我添加此约束,这很好,但我希望集成代码能够获得编译错误,即使它们从未尝试反序列化库中定义的结构。

use failure::Fallible; // 0.1.6
use serde::{Deserialize, Serialize}; // 1.0.104
use serde_json::to_string_pretty; // 1.0.44

#[derive(Deserialize, Serialize)]
struct X<T>
where
// T: Serialize,
{
a: u8,
t: T,
}

type Main<'a> = &'a dyn Fn() -> Fallible<()>;

fn main() -> Fallible<()> {
let x = X { a: 1, t: false };
println!("{}", to_string_pretty(&x)?);

let y: X<bool> = serde_json::from_str(r#"{"a":2,"t":true}"#)?;
println!("{}", y.t);

let _z: X<Main> = X { a: 3, t: &main };
// println!("{}", to_string_pretty(&z)?);

//let w: X<Main> = serde_json::from_str(r#"{"a":4,"t":NONONO}"#)?;

Ok(())
}

playground

  • 如果我用 to_string_pretty(&z) 取消注释该行,编译就会失败,这很好。
  • 即使没有该行,let _z = ... 上的编译也会失败。如果我取消注释 where T: Serialize 则行。这很棒,因为它可以帮助库集成商发现他们正在使用 struct X甚至在实际开始序列化之前就使用不可序列化的类型参数。

我尝试添加 where for<'a> T: serde::de::Deserialize<'a>作为 struct X<T> 的约束,但是即使没有任何使用 X 也会破坏构建

use serde::{Deserialize, Serialize};

#[derive(Deserialize, Serialize)]
struct X<T>
where
for<'a> T: serde::de::Deserialize<'a>,
{
a: u8,
t: T,
}

playground

有没有办法表达我正在寻找的这个约束?

最佳答案

您需要使用#[serde(bound)]防止 Serde 尝试自动确定 DeserializeSerialize 实现的边界:

use serde::{Deserialize, Serialize};

#[derive(Deserialize, Serialize)]
#[serde(bound = "T: Serialize, for<'de2> T: Deserialize<'de2>")]
struct X<T>
where
T: Serialize,
for<'de2> T: Deserialize<'de2>,
{
t: T,
}

struct NotSerializable;

fn main() {
X { t: true };

// X { t: NotSerializable }; // Generates compiler error
}

另请参阅:

关于generics - 限制 Rust 结构体的泛型参数进行反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59687019/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com