rust - 了解dbg!Rust 中的宏
问题描述
我正在尝试编写一些自己的调试宏,并且正在查看 rusts build in 的源代码dbg!
:
macro_rules! dbg {
() => {
$crate::eprintln!("[{}:{}]", $crate::file!(), $crate::line!());
};
($val:expr $(,)?) => {
// Use of `match` here is intentional because it affects the lifetimes
// of temporaries - https://stackoverflow.com/a/48732525/1063961
match $val {
tmp => {
$crate::eprintln!("[{}:{}] {} = {:#?}",
$crate::file!(), $crate::line!(), $crate::stringify!($val), &tmp);
tmp
}
}
};
($($val:expr),+ $(,)?) => {
($($crate::dbg!($val)),+,)
};
}
这段代码有几件事让我感到困惑:
$
贯穿这段代码的操作员在做什么?- 平面语言相当于
($val:expr $(,)?)
什么?我不明白,
它是什么以及它为什么在那里。 - 为什么宏定义以 开头
() => {$crate::eprintln!("[{}:{}]", $crate::file!(), $crate::line!());};
?
解决方案
贯穿这段代码的 $ 运算符在做什么?
macro_rules!
在普通 Rust 之上具有不同的语法。$
s 用于表示元变量(like )$ident
和重复(like $(...)
)。您可能应该对 Rust 宏是什么做一些初步研究:
- Rust 参考中的宏示例。
- 宏规则!在 Rust By Example 一书中。
- Rust 宏小书
平面语言相当于
($val:expr $(,)?)
什么?我不明白,
它是什么以及它为什么在那里。
$val:expr
定义将匹配单个表达式的模式。$(,)?
匹配的 a可能,
存在零次或一次。有效地使它dbg!
允许可选的尾随逗号(以模仿大多数 Rust)。您会在其他模式中看到这一点$($val:expr),+ $(,)?
。
为什么宏定义以 开头
() => {$crate::eprintln!("[{}:{}]", $crate::file!(), $crate::line!());};
?
该宏被设计为使用任意数量的参数调用,包括零。该() => { ... };
模式允许dbg!()
有效。不带参数调用的效果dbg!
是只记录文件和行号。
推荐阅读
- google-chrome - 检查*域名*中是否有错字
- google-cloud-platform - Google BigQuery 的资源窗口
- python - 系统找不到指定的文件 - Python语音识别
- c# - “参数”是一个“类型”,在给定的上下文中无效
- mongodb - zsh:找不到命令:MacOS 上的 mongo
- python - 根据索引对多维数组中的元素求和
- mysql - SQL GROUP BY INNER JOIN 和 COUNT
- php - Laravel 5.2:预期响应代码 220,但得到代码“500”,消息“500 Unrecognized command”
- asp.net-core - 在 Scrutor 中多次使用 AddClasses
- python - 哪个 numpy 索引是副本,哪个是视图?