Qua*_*Dot 4 compile-time rust rust-proc-macros
注意:这个问题并不是专门关于serde:它是关于过程宏和 const 函数。
我正在研究serde的派生宏为Serialize和生成的代码Deserialize,但我还没有弄清楚为什么它的所有代码都在const _: ().
例如,
#[derive(Deserialize)]
struct MyNewType(i32);
Run Code Online (Sandbox Code Playgroud)
扩展为(使用cargo expand):
#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const _: () = {
#[allow(unused_extern_crates, clippy::useless_attribute)]
extern crate serde as _serde;
#[automatically_derived]
impl<'de> _serde::Deserialize<'de> for MyNewType {
fn deserialize<__D>(
__deserializer: __D,
) -> _serde::__private::Result<Self, __D::Error>
where
__D: _serde::Deserializer<'de>,
{
// generated implementation omitted for brevity
}
}
};
Run Code Online (Sandbox Code Playgroud)
我发现,如果我仔细复制块内的内容const _: () = {...},并在删除标签后将其粘贴回源代码中#[derive(Deserialize)],那么一切似乎都会编译并且反序列化继续正常工作。const _: ()那么,在我的程序中将所有内容放入块中有何目的呢?
它防止将新名称引入外部范围。当您复制粘贴到自己的范围时,您也复制了这一行。
#[allow(unused_extern_crates, clippy::useless_attribute)]
extern crate serde as _serde;
Run Code Online (Sandbox Code Playgroud)
_serde这引入了一个被称为当前作用域的名称。如果您不知道查找它,这可能会与您自己的代码发生冲突。更糟糕的是,如果多个Deserialize宏在同一范围内扩展,那么它们都会引入相同的名称,这是一个问题。
const _: () = {
...
}
Run Code Online (Sandbox Code Playgroud)
因此,我们运行一个块来获取一个不会干扰任何内容的新本地范围。该块返回(),我们忽略了绑定。我不完全确定为什么他们需要一个变量(而不仅仅是大括号),尽管我怀疑它可能是为了抑制未使用的变量警告或防止死代码消除。
| 归档时间: |
|
| 查看次数: |
55 次 |
| 最近记录: |