gpt4 book ai didi

rust - 是否可以在 Rust "if"条件语句中使用宏扩展?

转载 作者:行者123 更新时间:2023-12-05 03:17:19 25 4
gpt4 key购买 nike

例如,想象一个理论上的 lets! 宏应该这样写:

if lets![Some(x) = x && Some(y) = y] {
...
}

这将扩展为:

if let Some(x) = x {
if let Some(y) = y {
...
}
}

我知道 if-let-chains Rust 即将推出,所以问题不在于这里的 let 链。相反,它更多的是提供最终不卫生的宏,因此结果代码应该只在扩展宏之后被解析——例如想象一个宏填充了 if 条件的一部分,并影响了扩展后的代码的解析方式。

Rust 可以实现这样的事情吗?

最佳答案

虽然理论上可行,但您设法选择了一种使用宏的较难的边缘情况。主要原因是此宏无法在不修改宏边界之外的区域的情况下扩展为所需的等效代码。让我们对您的示例稍加修改的示例版本来执行此操作,以说明这是有问题的。

if lets![Some(x) = a && Some(y) = b] {
// etc
}

这可能看起来很明显,但不可能扩展为两个嵌套的 if 语句,因为这需要在宏的范围之外添加额外的花括号。

if let Some(x) = a {
if let Some(y) = b {
// etc
} // <- How do we create this brace?
}

不过,简单的解决方案是将两个匹配项合并为一个匹配项。但是,我们将通过提前评估两个表达式来失去短路属性。不幸的是,这也是不可能的,因为 if let 被认为是一个特殊的表达式,并且发出 let x = y 本身并不是一个有效的表达式。这在未来可能会改变,但我对此表示怀疑,因为它需要在任意表达式中允许变量声明。

// Theoretical macro expansion
if let (Some(x), Some(y)) = (a, b) {
// etc
}

现在我在这里思考了一段时间,但我想不出一种方法来补救 if let 是特殊运算符的事实,我们需要发出一些介于 if 之间的标记{/* etc */} 可以用作 if let。即使是具有完全访问权限以发出他们想要的任何标记的程序宏也可能无法按照您描述的方式执行此操作。方便的是,最近在 [rust] 标签下提出的问题 ( Rust Procedural Macro - macro expansion ignores token `,` ) 提供了对此的一些见解。过程宏不能只是发出任意标记并期望将其放入汇编代码中。它们必须在使用它们的上下文中有效。例如,我们不希望宏像链接问题中那样添加不匹配的括号或多个逗号分隔值。宏需要覆盖整个 if 语句才能正确展开。

事实上,这可能就是流行if_chain 的原因crate 按照它的方式工作。如果您想要此功能并且不想添加夜间功能或花太多时间弄清楚如何使其工作,那么这个箱子可能是您的最佳选择。这是他们文档中关于如何使用宏的一个简单示例。

if_chain! {
if let Some(y) = x;
if y.len() == 2;
if let Some(z) = y;
then {
do_stuff_with(z);
}
}

关于rust - 是否可以在 Rust "if"条件语句中使用宏扩展?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74157931/

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