问题标签 [rust-macros]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
0 回答
126 浏览

rust - 在 build.rs 中触发宏扩展

我想使用 crate cpp创建一个宏,但是这个 crate 存在宏扩展问题。

语境

crate 通过采用cpp!{ ... }内联 C 代码的宏,将其内容编译为函数,并用生成的函数替换宏调用来工作。这是通过调用cpp_build::build("src/lib.rs").build.rs

问题

正如 crate 的作者所说,cpp!宏是在宏扩展发生之前编译的。这意味着它将尝试按原样解释宏的参数并在宏声明内部展开。

build.rs有没有一种方法可以在调用函数之前触发内部特定宏或文件的扩展cpp_build

0 投票
1 回答
883 浏览

string - 如何从声明性宏中返回新字符串?

所以我在这里,和 Rustlings 一起卡车,直到我在测试 4 中获得广泛支持。

它希望我编写一个满足以下代码的宏:

所以,我写了这个:

Rustlings 吐了出来:

哪个,你知道的。我明白了。我明白问题是什么,但我不明白如何编写一个满足代码的宏。我可以更改我正在测试的代码,但这不是测试要我做的。我只是写一个宏。我难住了。我也不明白将宏封装在模块中有何帮助,但测试表明这是对模块和宏的测试。

0 投票
0 回答
245 浏览

rust - 如何在 Rust 中对宏进行字符串化之前使其展开?

我正在尝试仅使用宏在 Rust 中编写一个 quine。为了做到这一点,我将main函数嵌入到宏f1中,并尝试嵌入f1in f2with的文字表示stringify!

到目前为止,这是我的代码:

不出所料,输出是:

我需要的是f1在被字符串化之前进行扩展,以便程序能够运行。我怎样才能做到这一点?

0 投票
4 回答
937 浏览

rust - How to simplify mathematical formulas with rust macros?

I must admit I'm a bit lost with macros. I want to build a macro that does the following task and I'm not sure how to do it. I want to perform a scalar product of two arrays, say x and y, which have the same length N. The result I want to compute is of the form:

x is const which elements are 0, 1, or -1 which are known at compile time, while y's elements are determined at runtime. Because of the structure of x, many computations are useless (terms multiplied by 0 can be removed from the sum, and multiplications of the form 1 * y[i], -1 * y[i] can be transformed into y[i], -y[i] respectively).

As an example if x = [-1, 1, 0], the scalar product above would be

To speed up my computation I can unroll the loop by hand and rewrite the whole thing without x[i], and I could hard code the above formula as

But this procedure is not elegant, error prone and very tedious when N becomes large.

I'm pretty sure I can do that with a macro, but I don't know where to start (the different books I read are not going too deep into macros and I'm stuck)...

Would anyone of you have any idea how to (if it is possible) this problem using macros?

Thank you in advance for your help!

Edit: As pointed out in many of the answers, the compiler is smart enough to remove optimize the loop in the case of integers. I am not only using integers but also floats (the x array is i32s, but in general y is f64s), so the compiler is not smart enough (and rightfully so) to optimize the loop. The following piece of code gives the following asm.

0 投票
1 回答
478 浏览

rust - 在宏中调用 `stringify!`

该宏在调用时编译:

这个没有:

这是因为stringify!($def)被传递到未评估的#[serde(...)]属性中。

有什么实用的解决方法吗?

0 投票
2 回答
1728 浏览

rust - Rust 宏:调用函数依赖于表达式

我有三个不同的函数,我想根据宏参数调用其中一个。这个参数应该是预处理的,这就是为什么我认为我需要把它写成expr. 但是,我似乎无法找到一种方法来区分expr宏中的不同情况。这是我的代码:

这会产生以下编译时错误:

如何修复这个程序,以便根据$number表达式调用不同的函数?

0 投票
1 回答
2295 浏览

rust - 如何通过 Rust 宏将表达式中的一个标识符替换为另一个标识符?

我正在尝试构建一个可以进行一些代码转换的宏,并且应该能够解析它自己的语法。这是我能想到的最简单的例子:

该宏应该能够用作为第三个参数提供的表达式中的第二个标识符替换第一个标识符。宏应该对第三个参数的语言有一定的了解(在我的特殊情况下,与示例相反,不会在 Rust 中解析)并递归地应用它。

在 Rust 中构建这样一个宏的最有效方法是什么?我知道proc_macro方法和方法macro_rules!。但是我不确定是否macro_rules!足够强大来处理这个问题,而且我找不到太多关于如何使用proc_macro. 谁能指出我正确的方向?

0 投票
1 回答
244 浏览

rust - 有没有办法在没有过程宏的属性中“做宏的事情”?

具体来说,我正在尝试将宏输出放入文档注释中。我很兴奋这正是我想要的:

下一步是用我的内容替换该字符串。据此我不会写#[doc=my_content!()],并且属性宏是程序性的,所以我需要另一个板条箱,而且(我认为)我的内容可以在不需要任何程序性宏功能的情况下生成。

有没有办法以某种方式使用“常规宏”来做到这一点,还是我不走运?

0 投票
1 回答
1670 浏览

rust - 如何扩展递归宏规则中的子模式?

我正在编写一个宏来方便地将enum类型变量中的嵌套结构与编译时模板匹配。这个想法是利用 Rust 的模式匹配在结构的某些位置强制执行特定值,或将变量绑定到其他有趣的位置。基本思想在我的实现中有效,但对于嵌套模式却失败了。我认为问题在于,一旦宏输入的一部分被解析,因为$<name>:pat它以后不能被解析为$<name>:tt.

为了避免模棱两可地使用术语模式,我将根据 Rust 文档使用以下符号:

  • 模式是出现在武器matchif let语句中的内容,并由片段说明符在宏中匹配$<name>:pat
  • 匹配器是宏中语法规则的左侧。
  • 模板是我的宏的输入部分,它决定了宏的扩展方式。

游乐场 MCVE

enum这是我正在使用的类型的简化版本:

例如,下面的表达式

可以通过这个宏调用来匹配:

在这里,成功匹配标识符namebody绑定到相应的子元素,expression并作为块中的变量作为第二个参数传递给宏。

这是我编写所述宏的努力:

对于非嵌套模板,它按预期工作,对于嵌套模板,我可以手动嵌套宏调用。但是,在单个宏调用中直接指定嵌套模板会失败并出现编译错误。

游乐场 MCVE

我怀疑错误是说它[Str(name), _, _]作为单个切片模式匹配,它被第三个宏规则接受,它导致类型不匹配。但是,我希望它是一个标记树,以便第二条规则可以将其分解为一系列模式。

我试图将第二条规则更改为,($exp:expr, $action:block, [$first:tt, $($rest:tt)*]) =>但这只会导致错误发生在外部级别。

需要对宏进行哪些修改才能递归地扩展此类模板?

(我不认为像在递归宏中那样使用令牌咀嚼来解析 Rust 中的匹配臂,因为我明确地想在模式中绑定标识符。)

这就是我期望宏调用扩展到的内容(为简洁起见,忽略不匹配的分支。此外,我通过后缀seq变量来模拟宏卫生):

完整的扩展有点冗长,但这个稍微缩短的版本抓住了应该发生的事情的本质:

最后,这是另一个游乐场链接,显示了递归扩展的各个步骤。它非常密集。

0 投票
1 回答
5426 浏览

rust - 为什么 proc-macros 必须在 proc-macro crate 中定义?

我试图为我的特征创建一个派生宏,以简化一些东西。

我遇到了一些问题:

#[proc_macro_derive]属性仅适用于proc-macrocrate 类型的 crate

并且,在小修复之后proc-macro=true

proc-macrocrate类型不能导出除带有#[proc_macro_derive]当前标记的函数之外的任何项目#[proc_macro_derive]

这种行为的原因是什么?