提问人:pr0gramista 提问时间:11/4/2023 最后编辑:cafce25pr0gramista 更新时间:11/4/2023 访问量:52
如何定义可以使用同一 crate 中的符号的宏
How to define a macro that can use symbols from the same crate
问:
我正在尝试创建自己的宏,其行为几乎与宏相似,但我想获得自己的结构,而不是获得一个。json!
serde::Value
我使用以下代码成功了一半,但宏不能在此文件之外使用,因为它显示“在此范围内找不到类型”或“在此范围内找不到宏”等错误。Person
json
use serde_derive::{Deserialize, Serialize};
use serde_json::json;
mod utils;
#[derive(Debug, Clone, Serialize, Deserialize)]
struct Person {
name: String,
age: u8,
}
#[macro_export]
macro_rules! person_parse {
($json:tt) => {
serde_json::from_value::<Person>(json!($json)).unwrap()
};
}
fn main() {
let john: Person = person_parse!({
"name": "John Doe",
"age": 43,
});
println!("{:?}", john);
}
答:
4赞
pr0gramista
11/4/2023
#1
宏扩展为普通代码,因此,如果未导入名称,则在使用该名称的文件中找不到该名称。您可以导入 Person 结构体和 json!宏,但这有点不符合人体工程学。但是,您可以在宏中使用完全限定的名称,这样您就不需要添加导入。
#[macro_export]
macro_rules! person_parse {
($json:tt) => {
serde_json::from_value::<$crate::Person>(serde_json::json!($json)).unwrap()
};
}
在这里,我们使用了一个$crate元变量,它指的是当前的 crate,我们在宏使用之前添加了它。serde_json::
json!
您可以在此处了解有关宏的更多信息:https://doc.rust-lang.org/reference/macros-by-example.html
评论
2赞
cafce25
11/4/2023
另一种方法是在宏中添加 。您可以使用短名称,并且用户不需要在范围内具有符号。use $crate::Person;
评论