gpt4 book ai didi

macros - 如何在 Rust 宏中通过引用捕获

转载 作者:行者123 更新时间:2023-11-29 08:26:49 25 4
gpt4 key购买 nike

我有一个生成匹配武器的宏:

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,
});

我应该更改什么才能在宏调用中直接使用表达式?

最佳答案

使用宏相当于将它扩展到的代码替换到它的调用站点中。这意味着如果宏扩展多次包含 $sort_by,代码将多次评估您作为 $sort_by 传入的表达式。如果表达式消耗了一些变量,这将是无效的。

这与函数调用的工作方式形成对比。如果将表达式传递给函数,它将在调用函数之前对其进行求值,并且只将结果传递给函数。

如果这是问题的根源,您可以通过将 $sort_by 分配给宏扩展中的局部变量来修复它,并且随后仅访问局部变量:

macro_rules! sort_by {
($query:ident, $sort_by:expr, { $($name:pat => $column:path,)+ }) => {
let sort_by = $sort_by;
match sort_by.column {
$(
$name => if sort_by.descending {
$query = $query.order_by($column.desc());
} else {
$query = $query.order_by($column.asc());
},
)+
}
}
}

(请注意,我无法对此进行测试,因为您的示例不完整。)

关于macros - 如何在 Rust 宏中通过引用捕获,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52587636/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com