理解 Rust tracing info(target: "") 宏和类型
Understanding Rust tracing info(target: "") macro and types
我一直很享受在 Rust 的类型系统中导航。但是当它进入宏时,我发现很难理解。在下面的示例中,为什么可以将 "target_name"
传递给 target
但不赋值然后传递赋值?您如何导航 macro in tracing 以使下面的内容对您来说显而易见?我从开发人员体验的角度和程序员的角度来问这个问题。 (我肯定在寻找“授人以渔”式的答案。)
info!(target: "target_name", "message"); // fine, must be cast to &str?
let target_name = "target_name"; // must be cast to String?
info!(target: target_name, "message"); // not fine
后一个调用的结果是:
error[E0435]: attempt to use a non-constant value in a constant
|
44 | info!(target: target_name, "message");
| ^^^^^^^^^^^ non-constant value
即使我切换到 &target_name.as_str()
,我认为它应该是恒定的(不像 String
那样可以增长)宏仍然失败并出现相同的错误。这是我的思维导图失败的地方。我能理解赋值时假定的类型是错误的,但是当我重铸它时,为什么会失败?
这里的解决方案是使用符合预期的类型的 const
,例如:
const target_name : &str = "target_name";
您通常可以查看这些宏的源代码 in the documentation,如下所示:
#[macro_export(local_inner_macros)]
macro_rules! info {
(target: $target:expr, $($arg:tt)+) => (
log!(target: $target, $crate::Level::Info, $($arg)+)
);
($($arg:tt)+) => (
log!($crate::Level::Info, $($arg)+)
)
}
那只是 log!
的包装,所以它的信息量不是特别大,而 log!
只是 __private_api_log
的包装,用处更小。
我一直很享受在 Rust 的类型系统中导航。但是当它进入宏时,我发现很难理解。在下面的示例中,为什么可以将 "target_name"
传递给 target
但不赋值然后传递赋值?您如何导航 macro in tracing 以使下面的内容对您来说显而易见?我从开发人员体验的角度和程序员的角度来问这个问题。 (我肯定在寻找“授人以渔”式的答案。)
info!(target: "target_name", "message"); // fine, must be cast to &str?
let target_name = "target_name"; // must be cast to String?
info!(target: target_name, "message"); // not fine
后一个调用的结果是:
error[E0435]: attempt to use a non-constant value in a constant
|
44 | info!(target: target_name, "message");
| ^^^^^^^^^^^ non-constant value
即使我切换到 &target_name.as_str()
,我认为它应该是恒定的(不像 String
那样可以增长)宏仍然失败并出现相同的错误。这是我的思维导图失败的地方。我能理解赋值时假定的类型是错误的,但是当我重铸它时,为什么会失败?
这里的解决方案是使用符合预期的类型的 const
,例如:
const target_name : &str = "target_name";
您通常可以查看这些宏的源代码 in the documentation,如下所示:
#[macro_export(local_inner_macros)]
macro_rules! info {
(target: $target:expr, $($arg:tt)+) => (
log!(target: $target, $crate::Level::Info, $($arg)+)
);
($($arg:tt)+) => (
log!($crate::Level::Info, $($arg)+)
)
}
那只是 log!
的包装,所以它的信息量不是特别大,而 log!
只是 __private_api_log
的包装,用处更小。