Macros 是否可以编写将表达式扩展N次的宏?(其中N为常数)
假设我们需要声明一个具有值的固定大小数组,其中数组的大小由一个常数定义,该常数可能会根据编译时设置而变化 例如:Macros 是否可以编写将表达式扩展N次的宏?(其中N为常数),macros,rust,Macros,Rust,假设我们需要声明一个具有值的固定大小数组,其中数组的大小由一个常数定义,该常数可能会根据编译时设置而变化 例如: 让我的_数组=将_扩展到_数组!(j,数组_大小,-v0[j]*f) 其中,ARRAY\u SIZE是一个常数,例如: const数组大小:usize=3 可以扩展到像 let my_array = [ {let j = 0; {-v0[j] * f}}, {let j = 1; {-v0[j] * f}}, {let j = 2; {-v0[j] * f}}
让我的_数组=将_扩展到_数组!(j,数组_大小,-v0[j]*f)代码>
其中,ARRAY\u SIZE
是一个常数,例如:
const数组大小:usize=3代码>
可以扩展到像
let my_array = [
{let j = 0; {-v0[j] * f}},
{let j = 1; {-v0[j] * f}},
{let j = 2; {-v0[j] * f}},
];
因为表达式是一个固定大小的数组,所以对于数量有限的项,可以使用模式匹配。。。例如,最多32个
是否可以编写一个基于常量整数将表达式展开N次的宏
细节
考虑到这一点,我编写了一个宏来定义数组,然后填充它,例如:
const ARRAY_SIZE: usize = 3;
macro_rules! expand_into_array {
($index_var:ident, $const_size:expr, $body:expr) => {
{
let mut tmp: [_; $const_size] = [0.0; $const_size];
for $index_var in 0..$const_size {
tmp[$index_var] = $body;
}
// TODO, check $body _never_ breaks.
tmp
}
}
}
pub fn negated_array(v0: &[f64; ARRAY_SIZE]) -> [f64; ARRAY_SIZE] {
expand_into_array!(j, ARRAY_SIZE, {
-v0[j]
})
}
除了褶皱(即$body
表达式可能包含一个break
)之外,它的工作原理与预期一样。这是没有问题的
但是,将数组初始化为0.0并没有得到优化(更改此值在使用以下命令运行时显示为更改:
c--release--emit asm
我宁愿不要使用不安全的{std::mem::uninitialized}
更新,从询问,似乎宏只能匹配文字,而不是常量
因此,对于生锈的宏来说,这是不可能的。这个问题是关于使用常量来声明数组的,另一个问题是关于动态向量的。虽然它们是相关的,但我不认为这是重复的。@ker:我认为这实际上与您链接的问题相反。计算重复次数很棘手,但可行,然而,这里的问题是当输入中没有重复(只有一个文字数字)时生成重复。你也许可以用一个聪明的表达式来替换宏调用中的T
s序列,这样你就可以传递索引。阅读所有标记为重复的3个问题,它们似乎都只是略微相关。虽然问题的每一个变体都没有用,但有必要在这里如此热情地标记重复项吗e其他问题似乎比这个问题更高级。@ideasman42:第一个()这个问题是关于使用常量来声明数组的,另一个问题是关于动态向量的。虽然它们是相关的,但我不认为这是重复的。@克尔:我认为这实际上与您链接的问题相反。计算重复次数很难,但可行,但这里的question是关于在输入中没有重复(只有一个文字数字)时生成重复。接近(接近固定长度)。你也许可以用一个聪明的表达式来替换宏调用中的T
s序列,这样你就可以传递索引。阅读所有标记为重复的3个问题,它们似乎都只是略微相关。虽然问题的每一个变体都没有用,但有必要在这里如此热情地标记重复项吗e其他问题似乎比这个问题要高级一些。@ideasman42:第一个()虽然简单,但实际上是正确的。