gpt4 book ai didi

rust - 如何在 `macro_rules!` 中声明一个变量?

转载 作者:行者123 更新时间:2023-12-03 11:43:53 27 4
gpt4 key购买 nike

我正在创建一个名为 throw_error 的宏。我希望它能编译,但它失败了:

// Util structs + types

...

// Util macros

#[macro_export]
macro_rules! throw_error {
() => {
RaptorexError {
message: String::new(),
line: line!(),
file: file!().to_owned(),
}
};

($($msg:tt),*) => {
let mut final_msg = String::new();

$(
final_msg.push_str(&format!("{} ", $msg));
)*

// remove trailing whitespace
final_msg.pop();

RaptorexError {
message: final_msg,
line: line!(),
file: file!(),
}
}
}

// Util functions

...

我在其他代码中使用宏时遇到了几个错误。

错误:

error: macro expansion ignores token `final_msg` and any following
--> /Users/henryboisdequin/Desktop/raptorex/raptorex_util/src/lib.rs:30:13
|
30 | final_msg.push_str(&format!("{} ", $msg));
| ^^^^^^^^^
|
::: compiler/src/parser/parser.rs:44:29
|
44 | _ => return Err(throw_error!("Unexpected token:", current_token)),
| ------------------------------------------------- help: you might be missing a semicolon here: `;`
| |
| caused by the macro expansion here
|
= note: the usage of `throw_error!` is likely invalid in expression context

error[E0658]: `let` expressions in this position are experimental
--> compiler/src/parser/parser.rs:44:29
|
44 | _ => return Err(throw_error!("Unexpected token:", current_token)),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
= help: add `#![feature(let_chains)]` to the crate attributes to enable
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: `let` expressions are not supported here
--> compiler/src/parser/parser.rs:44:29
|
44 | _ => return Err(throw_error!("Unexpected token:", current_token)),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: only supported directly in conditions of `if`- and `while`-expressions
= note: as well as when nested within `&&` and parenthesis in those conditions
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

warning: unused imports: `DATA_TYPES`, `KEYWORDS`
--> compiler/src/parser/parser.rs:3:28
|
3 | lexer::tokens::{Token, DATA_TYPES, KEYWORDS},
| ^^^^^^^^^^ ^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default

error[E0308]: mismatched types
--> compiler/src/parser/parser.rs:44:29
|
44 | _ => return Err(throw_error!("Unexpected token:", current_token)),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `raptorex_util::RaptorexError`, found `bool`
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 4 previous errors; 1 warning emitted

这些错误的原因是什么,我该如何解决?

最佳答案

您需要另一组 {},以便宏创建一个包含语句而不是单个语句本身的 block :

#[macro_export]
macro_rules! throw_error {
() => {
RaptorexError {
message: String::new(),
line: line!(),
file: file!().to_owned(),
}
};

($($msg:tt),*) => {
{ // <------------------
let mut final_msg = String::new();

$(
final_msg.push_str(&format!("{} ", $msg));
)*

// remove trailing whitespace
final_msg.pop();

RaptorexError {
message: final_msg,
line: line!(),
file: file!(),
}
} // <-------------------
}
}

(...) => {} 中的 {} 是宏语法的一部分,而不是生成代码的一部分。

关于rust - 如何在 `macro_rules!` 中声明一个变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66240468/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com