简体   繁体   中英

How do I create a match macro in rust?

I'm trying to complete Quiz #4 in the Rustlings exercises:

// Write a macro that passes the quiz, No hints this time, you can do it!

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_my_macro_world() {
        assert_eq!(my_macro!("world!"), "Hello world!");
    }

    #[test]
    fn test_my_macro_goodbye() {
        assert_eq!(my_macro!("goodbye!"), "Hello goodbye!");
    }
}

my macro looks like this:

#[macro_export]
macro_rules! my_macro {
    (($val:expr), "world!") => {
        println!("Hello world!");
    };
    (($val:expr), "goodbye!") => {
        println!("Hello goodbye!");
    };
}

This was patterned after the Declarative Macro section of the Rust Language Documentation. I get the following errors:

assert_eq!(my_macro!("world!"), "Hello world!");
   |                              ^^^^^^^^^^ no rules expected this token in macro call

assert_eq!(my_macro!("goodbye!"), "Hello goodbye!");
   |                              ^^^^^^^^^^ no rules expected this token in macro call

I cannot find a solution to this to make it compile. Help!

I think the idea of the exercise is to find a way that by using the macro we get the string "Hello whatever ". I'm a newbie at Rust too, but I've been able to do the exercise this way:

#[macro_use]
macro_rules! my_macro {
    ($val:expr) => {
        format!("Hello {}",$val);
    }
}

I'm waiting for feedback!

You shouldn't use format!() in a macro like in @Max's answer, you should use concat! instead, because it produces a string slice at compile time instead of formatting at runtime:

macro_rules! my_macro {
    ($val:tt) => {
        concat!("Hello ", $val);
    }
}

After clearing my head and thoroughly examining the error messages I figured it out. Here's the solution:

#[macro_export]
macro_rules! my_macro {
    ($("world!"),*) => {
        "Hello world!"
    };
    ($("goodbye!"),*) => {
        "Hello goodbye!"
    };
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_my_macro_world() {
        assert_eq!(my_macro!("world!"), "Hello world!");
    }

    #[test]
    fn test_my_macro_goodbye() {
        assert_eq!(my_macro!("goodbye!"), "Hello goodbye!");
    }
}

I was making it too complicated.

#[macro_use]
mod macros {
   macro_rules! my_macro {
     ($val: expr) => {
         concat!("Hello ", $val);
      };
   }
}

#[cfg(test)]
mod tests {
  use super::*;

  #[test]
  fn test_my_macro_world() {
     assert_eq!(my_macro!("world!"), "Hello world!");
  }

  #[test]
  fn test_my_macro_goodbye() {
      assert_eq!(my_macro!("goodbye!"), "Hello goodbye!");
  }
}

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM