I am doing the Rustlings Rust-lang course and working on exercises/test4.rs
This is the only exercise in the course that does not come with a hint. So after working on it for a while, I'm reaching out to get that hint here!
macro_rules! my_macro {
() => {
println!("Hello!");
};
($val:expr) => {
println!("Hello {}", $val);
}
}
fn main() {
if my_macro!("world!") != "Hello world!" {
panic!("Oh no! Wrong output!");
}
}
When I try to compile, I get the following error:
error[E0308]: mismatched types
--> test4.rs:20:31
|
20 | if my_macro!("world!") != "Hello world!" {
| ^^^^^^^^^^^^^^ expected (), found reference
|
= note: expected type `()`
found type `&'static str`
error: aborting due to previous error
The issue seems to be based on the fact that the default return type for a Rust macro is an empty tuple type (ie expected type ()
), where as we compare it to a static string.
If the parameters of the exercise would allow me to alter the code in the main function, then the exercise seems like it would be a bit simpler. However, according to the instruction, the only thing to be done is to write a macro that causes the code to compile.
As I understand it, you cannot explicitly declare a return type for a macro. So I am at a loss as to how to proceed.
So here is the working answer I came up with:
fn function_rules(expr:&str)-> String{
let a = "Hello";
let b = expr;
let result = [a, b].join(" ");
return result.to_string();
}
macro_rules! my_macro {
() => {
println!("Hello!");
};
($val:expr) => {
//println!("Hello {}", $val);
function_rules($val)
}
}
fn main() {
if my_macro!("world!") != "Hello world!" {
panic!("Oh no! Wrong output!");
}
}
I big part of solving this problem was dealing with String vs &str types, an excellent coverage of which can be found here.
The code compiles without modifying the main() function in any way, as per the instruction perameters. I think an even more elegant solution would have been to write a macro that returned the correct type without relying on an extra function. Assuming that's possible!