gpt4 book ai didi

macros - 错误 `cannot be named the same as a tuple variant` 是什么意思?

转载 作者:行者123 更新时间:2023-11-29 08:03:47 25 4
gpt4 key购买 nike

所以我在做一个基于simplecs的ECS .

我有一个生成实体结构的宏,如下所示:

($($name:ident : $component:ty,)*) => {
/// A collection of pointers to components
#[derive(Clone, Debug, Deserialize, PartialEq)]
pub struct Entity {
$(
pub $name: Option<($component)>,
)*
children: Vec<Entity>
}
}

我的目标是使用 serde 来序列化实体,但这在组件应该存在的地方留下了一堆难看的 None 值。所以我尝试实现一个如下所示的自定义序列化程序:

impl Serialize for Entity {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
let mut num_fields = 0;
$(
match self.$name {
Some => num_fields += 1,
None => {}
};
)*
let mut state = serializer.serialize_struct("Entity", num_fields)?;
// do serialize
state.end()
}
}

序列化程序尝试通过作为宏参数 ($name) 提供的名称来访问字段,但是当我编译它时,出现此错误

error[E0530]: match bindings cannot shadow tuple variants
|
| Some => {}
| ^^^^ cannot be named the same as a tuple variant

最佳答案

语法self.$name 访问成员变量是正确的。正如@oli_obk-ker 在问题的评论中所说,错误是由于使用 Some 而不是 Some(pattern) 造成的。

         match self.$name {
Some(_) => num_fields += 1,
// ^~~
None => {}
};
//
// even better, use `if self.$name.is_some() { num_fields += 1; }`.

但是,您甚至不需要编写自己的serialize。你可以使用 #[serde(skip_serializing_if = "f") attribute在字段上,如果 f(&self.field) 返回 true,这会导致生成的代码避免将其写出。

($($name:ident : $component:ty,)*) => {
/// A collection of pointers to components
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct Entity {
$(
#[serde(skip_serializing_if = "Option::is_none")] // <-- add this
pub $name: Option<($component)>,
)*
children: Vec<Entity>
}
}

关于macros - 错误 `cannot be named the same as a tuple variant` 是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46065487/

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