前几天产生用宏代码重写变换矩阵类与几何体点(Point)等类的想法,自然没有继续写圆等其它几何体类代码的计划。初步考虑用声明类实现。经过百度后发现,声明宏是一个编程思路比较特别的工具,用起来很不顺手,需要很长时间适应,而且rust语言开发人员也有改写声明宏规则的意愿。我果断放弃,选用函数式过程宏。
`函数式过程宏必须写在一个独立的库项目中,起码现在是这样。我新建了一个库项目“matrix_macro”,在对应Cargo.toml文件中添加如下内容:
[lib]
proc-macro=true # 开启过程宏
lib.rs文件完成结构体定义,如下:
use proc_macro::TokenStream;
const MATRIX_LIST:[[&str; 7]; 5]=[
["Matrix","f64","f64","f64","f64","f64","f64"],//组合矩阵Matrix
["NonShear","f64","f64","f64","0","0","f64"],//非切变矩阵NonShear
["Rotate","0","0","f64","f64","f64","f64"],//旋转矩阵Rotate
["Scale","0","0","f64","0","0","f64"],//缩放矩阵Scale
["Move","f64","f64","1","0","0","1"]//平移矩阵Move
];
#[proc_macro]
pub fn define_matrix{_input: TokenStream} -> TokenStream {
let Mut output="use std::ops::{Mul,Div};\n"
for int j:0..5{
//结构定义
output+=format!("
#[derive(Clone,Copy)]\n
pub struct {0} {\n
{1}\n{2}\n{3}\n{4}\n{5}\n{6}\n
}",
MATRIX_LIST[j][0],
if MATRIX_LIST[j][1]!="0"|| MATRIX_LIST[j][1]!="1"{"m01:f64,"}else{""},
if MATRIX_LIST[j][2]!="0"|| MATRIX_LIST[j][2]!="1"{"m02:f64,"}else{""},
if MATRIX_LIST[j][3]!="0"|| MATRIX_LIST[j][3]!="1"{"m11:f64,"}else{""},
if MATRIX_LIST[j][4]!="0"|| MATRIX_LIST[j][4]!="1"{"m12:f64,"}else{""},
if MATRIX_LIST[j][5]!="0"|| MATRIX_LIST[j][5]!="1"{"m21:f64,"}else{""},
if MATRIX_LIST[j][6]!="0"|| MATRIX_LIST[j][6]!="1"{"m22:f64,"}else{""},
)
//new函数定义
output+=format!("
fn new(){}
pub struct {0} {\n
{1}\n{2}\n{3}\n{4}\n{5}\n{6}\n
}",
MATRIX_LIST[j][0],
if MATRIX_LIST[j][1]!="0"|| MATRIX_LIST[j][1]!="1"{"m01:f64,"}else{""},
if MATRIX_LIST[j][2]!="0"|| MATRIX_LIST[j][2]!="1"{"m02:f64,"}else{""},
if MATRIX_LIST[j][3]!="0"|| MATRIX_LIST[j][3]!="1"{"m11:f64,"}else{""},
if MATRIX_LIST[j][4]!="0"|| MATRIX_LIST[j][4]!="1"{"m12:f64,"}else{""},
if MATRIX_LIST[j][5]!="0"|| MATRIX_LIST[j][5]!="1"{"m21:f64,"}else{""},
if MATRIX_LIST[j][6]!="0"|| MATRIX_LIST[j][6]!="1"{"m22:f64,"}else{""},
)
}
output.parse().unwrap()
}