我有一个宏可以生成match
臂:
macro_rules! sort_by {
( $query:ident, $sort_by:expr, { $( $name:pat => $column:path,)+ } ) => {
match $sort_by.column {
$(
$name => if $sort_by.descending {
$query = $query.order_by($column.desc());
} else {
$query = $query.order_by($column.asc());
},
)+
}
}
}
我想这样称呼它:
sort_by!(query, sort_by.unwrap_or(Sort::desc("id")), {
"id" => table::id,
"customerName" => table::customer_name,
});
但是我遇到一个错误:
sort_by!(query, &sort_by.unwrap_or(Sort::desc("id")), {
^^^^^^^ value moved here in previous iteration of loop
所以我必须这样称呼它:
let sort = sort_by.unwrap_or(Sort::desc("id"));
sort_by!(query, &sort, {
"id" => table::id,
"customerName" => table::customer_name,
});
为了能够直接在宏调用中使用表达式,我应该进行哪些更改?
答案 0 :(得分:2)
使用宏等同于将其扩展的代码替换为其调用位置。这意味着如果宏扩展多次包含and s.sale_id in (SELECT thing FROM new_table)
,则代码将对您多次作为$sort_by
传递的表达式求值。如果表达式使用某些变量,则将无效。
这与函数调用的工作方式相反。如果将表达式传递给函数,则将在调用该函数之前对该表达式求值,并且仅将结果传递给该函数。
如果这是问题的根源,则可以通过将$sort_by
分配给宏扩展内的局部变量来解决此问题,并且仅在随后访问该局部变量:
$sort_by
(请注意,由于您的示例不完整,因此我无法对此进行测试。)