Unlike Python and several other programming languages, Rust does not allow setting default values to function parameters. Luckily with a little bit of macro-writing we can imitate it.
Here is the whole example
examples/default-arguments/src/main.rs
fn prompt(text: &str, count: u8) {
println!("prompt '{}' {} times", text, count);
}
macro_rules! prompt {
($text: expr, $count: expr) => {
prompt($text, $count);
};
($text: expr) => {
prompt($text, 5);
};
}
fn main() {
prompt("What is your secret?", 3);
prompt!("Still with me?", 4);
prompt!("What is the default?");
}
When we run this we get the following output:
prompt 'What is your secret?' 3 times
prompt 'Still with me?' 4 times
prompt 'What is the default?' 5 times
Explanation
fn prompt(text: &str, count: u8) {
println!("prompt '{}' {} times", text, count);
}
We have a function that accepts two parameters. A text and a number. If really implemented it I'd have ask the user with the prompt up to count times to answer the question, but we are not here for that.
We would like to have a default value for the count parameter, but Rust does not have that feature.
Use of the function
In the main function above you can see how can we use the function:
prompt("What is your secret?", 3);
Use of the macro
You can also see that we can use the prompt! macro both with and without the 2nd argument.
prompt!("Still with me?", 4);
prompt!("What is the default?");
Write a macro
macro_rules! prompt {
($text: expr, $count: expr) => {
prompt($text, $count);
};
($text: expr) => {
prompt($text, 5);
};
}
The line macro_rules! prompt means that our new macro will be called prompt and we will be able to use it as prompt!. That exclamation mark
at the end of the name indicates that this is a macro. This is also good, because this way we can use the same name as our function.
Inside the macro definition there are two rules.
The first rule expects 2 expressions that will be called $text and $count.
We could really call them anything, but using the same names as are used in the function seemed to make sense.
If the compiler encounters prompt! with two parameters, this rule will be matched and the macro will be replaced by a call to the prompt function passing the two parameters to it.
($text: expr, $count: expr) => {
prompt($text, $count);
};
The second rule expects only one parameter we called $text and then replaces the macro with a call to the prompt function with the
parameter we received and the number 5 which is now the default value of the count parameter.
($text: expr) => {
prompt($text, 5);
};
Conclusion
Macros can be really simple and useful.