Matrix 是否可以编写转换矩阵的rust宏?

Matrix 是否可以编写转换矩阵的rust宏?,matrix,rust,macros,transpose,rust-macros,Matrix,Rust,Macros,Transpose,Rust Macros,我目前正在使用SIMD。为了避免代码中的长时间重复,我想编写一个宏来生成以下矩阵转置代码: s=[ i32x8::新建(s[0]。摘录(0),s[1]。摘录(0),s[2]。摘录(0),s[3]。摘录(0),s[4]。摘录(0),s[5]。摘录(0),s[6]。摘录(0),s[7]。摘录(0),), i32x8::新建(s[0]。摘录(1),s[1]。摘录(1),s[2]。摘录(1),s[3]。摘录(1),s[4]。摘录(1),s[5]。摘录(1),s[6]。摘录(1),s[7]。摘录(1),)

我目前正在使用SIMD。为了避免代码中的长时间重复,我想编写一个宏来生成以下矩阵转置代码:

s=[
i32x8::新建(s[0]。摘录(0),s[1]。摘录(0),s[2]。摘录(0),s[3]。摘录(0),s[4]。摘录(0),s[5]。摘录(0),s[6]。摘录(0),s[7]。摘录(0),),
i32x8::新建(s[0]。摘录(1),s[1]。摘录(1),s[2]。摘录(1),s[3]。摘录(1),s[4]。摘录(1),s[5]。摘录(1),s[6]。摘录(1),s[7]。摘录(1),),
i32x8::新建(s[0]。摘录(2),s[1]。摘录(2),s[2]。摘录(2),s[3]。摘录(2),s[4]。摘录(2),s[5]。摘录(2),s[6]。摘录(2),s[7]。摘录(2),),
i32x8::新建(s[0]。摘录(3),s[1]。摘录(3),s[2]。摘录(3),s[3]。摘录(3),s[4]。摘录(3),s[5]。摘录(3),s[6]。摘录(3),s[7]。摘录(3),),
i32x8::新建(s[0]。摘录(4),s[1]。摘录(4),s[2]。摘录(4),s[3]。摘录(4),s[4]。摘录(4),s[5]。摘录(4),s[6]。摘录(4),s[7]。摘录(4),),
i32x8::新建(s[0]。摘录(5),s[1]。摘录(5),s[2]。摘录(5),s[3]。摘录(5),s[4]。摘录(5),s[5]。摘录(5),s[6]。摘录(5),s[7]。摘录(5),),
i32x8::新建(s[0]。摘录(6),s[1]。摘录(6),s[2]。摘录(6),s[3]。摘录(6),s[4]。摘录(6),s[5]。摘录(6),s[6]。摘录(6),s[7]。摘录(6),),
i32x8::新建(s[0]。摘录(7),s[1]。摘录(7),s[2]。摘录(7),s[3]。摘录(7),s[4]。摘录(7),s[5]。摘录(7),s[6]。摘录(7),s[7]。摘录(7),),
];
宏应该能够为不同的矩阵大小(4或8)生成代码

我尝试过几种不同的方法,但我从未设法使宏重复n次n项模式

我认为最符合逻辑的是:

macro\u规则!方格{
($($x:tt),*),($($y:tt),*)=>{
[
$([ 
$(s[$x]。摘录($y)),*
]),*
]
};
($($x:expr),*)=>{square!($($x),*),($($x),*)};
}
但它失败了

error: attempted to repeat an expression containing no syntax variables matched as repeating at this depth

您可以这样做,但需要通过递归处理外部重复:

macro_rules! square {
    (@row [$($acc:expr),*] [$($before:expr),*] $current:expr $(, $after:expr)*) => {
        square!(@row
            [ $($acc,)*
              stringify!($(s[$current].extract ($before),)*
                         s[$current].extract ($current)
                         $(, s[$current].extract ($after))*) ]
            [ $($before,)* $current ]
            $($after),*)
    };
    (@row [$($acc:tt)*] [$($before:expr),*]) => { vec![ $($acc)* ] };
    ($($r:expr),*) => {
        square!(@row [] [] $($r),*)
    };
}

我叫了
stringify
这样代码就可以在操场上编译,而不需要依赖项。您需要替换它们以满足您的需要(可能只需删除
stringify!
调用并用传递给宏的标识符替换
s


将值累加到
$acc
中,并在递归结束时一次输出所有值的想法称为。如果您不熟悉此概念,将在中详细介绍。

您可以这样做,但您需要通过递归处理外部重复:

macro_rules! square {
    (@row [$($acc:expr),*] [$($before:expr),*] $current:expr $(, $after:expr)*) => {
        square!(@row
            [ $($acc,)*
              stringify!($(s[$current].extract ($before),)*
                         s[$current].extract ($current)
                         $(, s[$current].extract ($after))*) ]
            [ $($before,)* $current ]
            $($after),*)
    };
    (@row [$($acc:tt)*] [$($before:expr),*]) => { vec![ $($acc)* ] };
    ($($r:expr),*) => {
        square!(@row [] [] $($r),*)
    };
}

我叫了
stringify
这样代码就可以在操场上编译,而不需要依赖项。您需要替换它们以满足您的需要(可能只需删除
stringify!
调用并用传递给宏的标识符替换
s


将值累加到
$acc
中,并在递归结束时一次输出所有值的想法称为。如果您不熟悉此概念,将在中详细介绍。

太好了,谢谢!我错过的关键元素是在递归时保留已经看到的元素的历史记录(之前的$1)。太好了,谢谢!我错过的关键元素是在递归时保留已经看到的元素(之前的$before)的历史记录。