< 返回版块

auyang-0626 发表于 2021-05-13 15:23

如下代码,我想利用宏自动创建实体的insert方法,其中field是实体的字段数组, 我想把拼接测values作为表达式,让rust可以解析,该怎么做呢

macro_rules! create_insert {
    // 此宏接受一个 `ident` 指示符表示的参数,并创建一个名为 `$func_name` 的函数。
    // `ident` 指示符用于变量名或函数名
    ($field:ident) => (

        fn insert(&self) {

            let sql = format!("INSERT INTO `data_source` ({}) VALUES ({})",
                 $field.iter().filter(|&x|*x != "id").map(|x|format!("`{}`",x)).collect::<Vec<String>>().join(","),
                 $field.iter().filter(|&x|*x != "id").map(|x|format!(":{}",x)).collect::<Vec<String>>().join(",")
            );
            let values = $field.iter().filter(|&x|*x != "id").map(|x|format!("self.{}.to_string()",x)).collect::<Vec<String>>().join(",")
            crate::dao::get_conn().exec_drop(sql,
                Params::from((values))
                //Params::from((self.name.to_string(), self.display_name.to_string(), self.created_by.to_string(), self.updated_by.to_string(), "2021-04-26 02:53:36", "2021-04-26 02:53:36")),
            ).unwrap();

            println!("You called insert")
        }
    )
}

评论区

写评论
Peacess 2021-05-14 09:04

声明宏只是字符串的替换,它很像功能强大的正规表达式。所以$field不能是一个集合,可以使用下面类似的方法:

macro_rules! macro_f { ($($field:expr),+) => { fn tt(){ let fields: Vec = vec![$($field),+]; println!("{:?}",t); } }; }

注:因为声明宏不能取到struct的字段名,而过程宏可以,所这个需要使用过程宏可能会更好

1 共 1 条评论, 1 页