Reputation: 18918
I have the following code:
trait Trait {
const NAME: &'static str;
const VALUE: i64;
}
struct Struct1 {}
struct Struct2 {}
impl Trait for Struct1 {
const NAME: &'static str = "Aardvark";
const VALUE: i64 = 0;
}
impl Trait for Struct2 {
const NAME: &'static str = "Zebra";
const VALUE: i64 = 100;
}
macro_rules! print_static {
($n:expr, $v:expr) => {
println!("Value of {} is {}", $n, $v);
};
}
macro_rules! print_static2 {
($t:expr) => {
println!("Value of {} is {}", $t::NAME, $t::VALUE);
};
}
fn main() {
print_static!(Struct1::NAME, Struct1::VALUE);
print_static!(Struct2::NAME, Struct2::VALUE);
//print_static2!(Struct1);
//print_static2!(Struct2);
}
It runs as:
Value of Aardvark is 0
Value of Zebra is 100
When I uncomment the print_static2
lines, I get:
error: expected one of `,`, `.`, `?`, or an operator, found `::`
--> src/main.rs:28:41
|
28 | println!("Value of {} is {}", $t::NAME, $t::VALUE);
| ^^ expected one of `,`, `.`, `?`, or an operator
...
37 | print_static2!(Struct1);
| ------------------------ in this macro invocation
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: expected one of `,`, `.`, `?`, or an operator, found `::`
--> src/main.rs:28:41
|
28 | println!("Value of {} is {}", $t::NAME, $t::VALUE);
| ^^ expected one of `,`, `.`, `?`, or an operator
...
38 | print_static2!(Struct2);
| ------------------------ in this macro invocation
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
Is there a way to specify the type name only once so that I don't end up doing something like this?
// Incorrectly associating Struct2's value with Struct1!
print_static!(Struct1::NAME, Struct2::VALUE);
Upvotes: 4
Views: 1586
Reputation: 12922
If you want to take a type as the parameter, say that:
macro_rules! print_static {
($t:ty) => {
println!("Value of {} is {}", <$t>::NAME, <$t>::VALUE);
};
}
Here's the full list of macro parameter types.
Upvotes: 7