I've been enjoying navigating Rust through its type system. But when it goes into macros I find it difficult to follow. In the below example, why is it ok to pass "target_name"
to target
but not assign it then pass the assignment in? How do you navigate the macro in tracing such that the below is obvious to you? I am asking this as much from a developer experience perspective as a programmer. (I'm definitely looking for a "teach a man to fish" style answer.)
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
The latter call results in:
error[E0435]: attempt to use a non-constant value in a constant
|
44 | info!(target: target_name, "message");
| ^^^^^^^^^^^ non-constant value
Even if I switch to &target_name.as_str()
which I believe should be constant (not growable like String
) the macro still fails with the same error. This is where my mental map is failing. I can understand that the assumed type when assigning is wrong, but then when I recast it, why would it fail?
The solution here is to use a const
with a type that's compatible with expectations, like:
const target_name : &str = "target_name";
You can usually view the source for these macros in the documentation , as shown here:
#[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)+)
)
}
That's just a wrapper around log!
, so it's not especially informative, and log!
is just a wrapper around __private_api_log
which is even less helpful.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.