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:第一个()虽然简单,但实际上是正确的。