如果值为false,我希望跳过字段序列化。在JSON中,这会将Foo序列化为{bar: true}或{}。
false
Foo
{bar: true}
{}
#[derive(Serialize)] pub struct Foo { // This does not compile - bool::is_false does not exist #[serde(skip_serializing_if = "bool::is_false")] pub bar: bool, }
wztqucjr1#
好吧,根据塞尔德的记录:第一个月调用函数以确定是否跳过序列化此字段。给定函数必须可作为fn(&T) -> bool调用,尽管它可能是T的泛型函数因此,您可以自己定义这样的函数,
fn(&T) -> bool
T
fn is_false(b: &bool) -> bool { !b }
或者您可以在标准库中查找这样的函数。
Clone::clone
std::ops::Not::not
注意bool::not不起作用,因为您需要&bool上的Not impl:<&bool as std::ops::Not>::not
bool::not
&bool
Not
<&bool as std::ops::Not>::not
vmjh9lq92#
为了只在布尔值为false时跳过序列化,您应该定义一个函数,当您想跳过序列化时,该函数返回true,如下所示:
fn is_false(b: &bool) -> bool { *b == false }
然后像#[serde(skip_serializing_if = "is_false")]一样注解该结构体。下面是完整的示例和playground link:
#[serde(skip_serializing_if = "is_false")]
use serde::Serialize; #[derive(Serialize)] pub struct Foo { #[serde(skip_serializing_if = "is_false")] pub bar: bool, } fn main() { let test1 = Foo { bar: true }; let test2 = Foo { bar: false }; println!("{}", serde_json::to_string(&test1).unwrap()); println!("{}", serde_json::to_string(&test2).unwrap()); } fn is_false(b: &bool) -> bool { *b == false }
您也可以跳过序列化默认值,如下所示:
use serde::Serialize; #[derive(Serialize)] pub struct Foo { #[serde(default, skip_serializing_if = "is_default")] pub bar: bool, } fn main() { let test1 = Foo { bar: true }; let test2 = Foo { bar: false }; println!("{}", serde_json::to_string(&test1).unwrap()); println!("{}", serde_json::to_string(&test2).unwrap()); } fn is_default<T: Default + PartialEq>(t: &T) -> bool { t == &T::default() }
这里是对应的playground。
2条答案
按热度按时间wztqucjr1#
好吧,根据塞尔德的记录:
第一个月
调用函数以确定是否跳过序列化此字段。给定函数必须可作为
fn(&T) -> bool
调用,尽管它可能是T
的泛型函数因此,您可以自己定义这样的函数,
或者您可以在标准库中查找这样的函数。
Clone::clone
std::ops::Not::not
(Playground)注意
bool::not
不起作用,因为您需要&bool
上的Not
impl:<&bool as std::ops::Not>::not
vmjh9lq92#
为了只在布尔值为false时跳过序列化,您应该定义一个函数,当您想跳过序列化时,该函数返回true,如下所示:
然后像
#[serde(skip_serializing_if = "is_false")]
一样注解该结构体。下面是完整的示例和playground link:
您也可以跳过序列化默认值,如下所示:
这里是对应的playground。