0

我正在上 Rustlings Rust-lang课程并致力于exercises/test4.rs

这是课程中唯一没有提示的练习。因此,在研究了一段时间之后,我正在伸出手来获得这个提示!

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

fn main() {
    if my_macro!("world!") != "Hello world!" {
        panic!("Oh no! Wrong output!");
    }
}

当我尝试编译时,出现以下错误:

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

这个问题似乎是基于这样一个事实,即 Rust 宏的默认返回类型是一个空元组类型(即expected type ()),当我们将它与静态字符串进行比较时。

如果练习的参数允许我更改主函数中的代码,那么练习似乎会更简单一些。但是,根据指令,唯一要做的就是编写一个宏来使代码编译。

据我了解,您不能显式声明宏的返回类型。所以我不知道如何进行。

4

2 回答 2

1

我认为实现可能要简单得多:

macro_rules! my_macro {
    ($val:expr) => {
        format!("Hello {}", $val)
    }
}
于 2020-01-11T16:43:14.007 回答
0

所以这是我想出的工作答案:

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!");
    }
}

我解决这个问题的很大一部分是处理 String 与 &str 类型,可以在这里找到一个很好的覆盖范围。

根据指令参数,代码无需以任何方式修改 main() 函数即可编译。我认为一个更优雅的解决方案是编写一个返回正确类型而不依赖额外函数的宏。假设这是可能的!

于 2019-12-22T01:25:45.893 回答