为什么调用以下宏时需要分号?
Why does the following macro expect a semi-colon when called?
我正在尝试编写一个宏来根据构建功能在人造丝的 par_iter
和标准的 iter
之间切换(可能会超前,因为我没有阅读很多关于宏)。宏在这里似乎比函数更好处理,因为函数可能需要一些相对复杂的类型才能完成这项工作;如果我想在与如何 运行 迭代器有关的构建功能中添加更多变化,那么宏在未来可能会保持更加灵活。
#[macro_export]
macro_rules! par_iter {
($($tokens:tt)*) => {
#[cfg(feature = "threaded")]
$($tokens)*.par_iter()
#[cfg(not(feature = "threaded"))]
$($tokens)*.iter()
}
}
我看到以下错误:
error: macro expansion ignores token `b_slice` and any following
--> src/util.rs:28:8
|
28 | $($tokens)*.iter();
| ^^^^^^^^^
|
::: src/counting.rs:219:9
|
219 | par_iter!(b_slice).map(WordCount::from)
| ------------------- help: you might be missing a semicolon here: `;`
| |
| caused by the macro expansion here
|
= note: the usage of `par_iter!` is likely invalid in expression context
虽然我不知道第一个错误,但我很好奇为什么会出现 ;
- 如何使其在表达式上下文中有效?
这基本上可以归结为,不允许在这样的表达式中使用 attributes,例如以下内容无效:
b_slice.iter()
#[cfg(not(feature = "threaded"))]
.map(|x| x)
.collect();
要解决此问题,您可以将它们分配给一个临时变量,如下所示:
注意双 {{
和 }}
,这会导致 block,这样最终的表达式就是块导致的值。
#[macro_export]
macro_rules! par_iter {
($($tokens:tt)*) => {{
#[cfg(feature = "threaded")]
let it = $($tokens)*.par_iter();
#[cfg(not(feature = "threaded"))]
let it = $($tokens)*.iter();
it
}};
}
或者,您也可以将其拆分为两个宏,如下所示:
#[cfg(feature = "threaded")]
#[macro_export]
macro_rules! par_iter {
($($tokens:tt)*) => {
$($tokens)*.par_iter()
}
}
#[cfg(not(feature = "threaded"))]
#[macro_export]
macro_rules! par_iter {
($($tokens:tt)*) => {
$($tokens)*.iter()
}
}
我正在尝试编写一个宏来根据构建功能在人造丝的 par_iter
和标准的 iter
之间切换(可能会超前,因为我没有阅读很多关于宏)。宏在这里似乎比函数更好处理,因为函数可能需要一些相对复杂的类型才能完成这项工作;如果我想在与如何 运行 迭代器有关的构建功能中添加更多变化,那么宏在未来可能会保持更加灵活。
#[macro_export]
macro_rules! par_iter {
($($tokens:tt)*) => {
#[cfg(feature = "threaded")]
$($tokens)*.par_iter()
#[cfg(not(feature = "threaded"))]
$($tokens)*.iter()
}
}
我看到以下错误:
error: macro expansion ignores token `b_slice` and any following
--> src/util.rs:28:8
|
28 | $($tokens)*.iter();
| ^^^^^^^^^
|
::: src/counting.rs:219:9
|
219 | par_iter!(b_slice).map(WordCount::from)
| ------------------- help: you might be missing a semicolon here: `;`
| |
| caused by the macro expansion here
|
= note: the usage of `par_iter!` is likely invalid in expression context
虽然我不知道第一个错误,但我很好奇为什么会出现 ;
- 如何使其在表达式上下文中有效?
这基本上可以归结为,不允许在这样的表达式中使用 attributes,例如以下内容无效:
b_slice.iter()
#[cfg(not(feature = "threaded"))]
.map(|x| x)
.collect();
要解决此问题,您可以将它们分配给一个临时变量,如下所示:
注意双 {{
和 }}
,这会导致 block,这样最终的表达式就是块导致的值。
#[macro_export]
macro_rules! par_iter {
($($tokens:tt)*) => {{
#[cfg(feature = "threaded")]
let it = $($tokens)*.par_iter();
#[cfg(not(feature = "threaded"))]
let it = $($tokens)*.iter();
it
}};
}
或者,您也可以将其拆分为两个宏,如下所示:
#[cfg(feature = "threaded")]
#[macro_export]
macro_rules! par_iter {
($($tokens:tt)*) => {
$($tokens)*.par_iter()
}
}
#[cfg(not(feature = "threaded"))]
#[macro_export]
macro_rules! par_iter {
($($tokens:tt)*) => {
$($tokens)*.iter()
}
}