appendix Exercise solutions

 

Chapter 2

  1. Fill in the question marks (???), and make the following declarative macro compile.

This is one possible solution. ty seems most appropriate, though ident—for example—would also work:

macro_rules! hello_world {
    ($something:ty) => {
        impl $something {
            fn hello_world(&self) {
                println!("Hello world!")
            }
        }
    };
}

struct Example {}
hello_world!(Example);

fn main() {
    let e = Example {};
    e.hello_world();
}
  1. In our first declarative macro example, we use expr in some of our matches. But that was not our only option. Try to replace that with literal, tt, ident, or ty. Which ones work? Which don’t? Do you understand why?

literal will work because we are passing in literal values (e.g., my_vec!(1, 2, 3)). tt will work as well. As we said, it accepts basically anything. ident will not work because we are not passing in identifiers. A valid example—that would get accepted—might be NameOfThisStructIDeclaredInMyCode. ty will not work either, because we are not passing in types. Valid examples include String, i32, etc.

  1. Allow trailing comments in the my_vec macro. You can do this by writing another matcher, but there’s a simple solution with even less repetition. If you need help, take a look at the vec macro from the standard library for inspiration.

This solution is based on the standard library code:

Chapter 3

Chapter 4

Chapter 5

Chapter 6

Chapter 7

Chapter 8

Chapter 9

Chapter 10