磁盘使用 proc
![](https://i-blog.csdnimg.cn/blog_migrate/38d550f1b2020d14fb14e9fcff071991.png)
我最近一直在从事一个名为Thruster的项目,并且需要一种开发人员可以合理使用模板的方式。 Thruster是一个用Rust编写的基于中间件的Web服务器(得到它,th-rust-er?我正在The Apollo上度过我的业余5晚上),因此,我需要一种加载HTML模板并插入的方法变量以一种高效的方式进入它们。 与其四处逛逛现有的图书馆,再选择一个我不认识的人制造的图书馆,不如说是陌生的危险! 我决定自己做。 本文是关于这一旅程的,这是在Rust中编写我的第一个proc_macro_derive
令人难以置信的惊险冒险。 提示印第安纳琼斯音乐 。
您需要知道的第一件事是,我不是我所说的系统专家。 我之所以选择rust,是因为我想要一种基于性能的更新语言,但实际上我是一名Web开发人员。 我已经可以通过互联网管道听到你的盐分了; “为什么我会从网络开发人员那里征求意见? 他可能只想谈论箭头功能以及他这一代人如何发现功能编程 。” 好吧,你是对的。 我只是想谈谈这件事,但是我也正在做鳄梨吐司,我的生活教练说我应该专心致志,而不是谈论榆木郎。
我之所以提到我是一名Web开发人员,是因为我在Web框架中寻找的第一件事之一是该框架中的开发有多么复杂,以及框架的组成和移动部分有多容易。 有时候,我希望能够复制/粘贴已经在不同项目中编写的代码,而不必重新计算将人送上月球的轨迹。
您应该知道的第二件事是Rust很棒,尽管我什至看起来好像要谈论它的内存安全性或极快的速度,我的同事们都想砸我的头,但我对它的热爱仍在继续比一千个太阳更明亮。
太好了,既然the悔室已经挡不住了,我们实际上可以深入研究该项目的实质; proc_macro_derive
。 程序宏(以及通常的宏)是令人着迷的生物。 许多其他语言的开发人员会睁大眼睛,回想起每次调试一个神秘的宏的过程,但是Rust却有所不同。 从文档:
…Rust有卫生的宏观体系 。 每个宏扩展都在不同的“语法上下文”中发生,并且每个变量都在引入变量的语法上下文中进行标记。
这是我要为宏完成的工作:
- 它应该在编译期间而不是在运行时从文件中提取模板。
- 它是类型安全的,即我不会惊慌! 或运行时在渲染的模板中出现一些奇怪的
undefined
类型文本。 - 很快
不幸的是,这里的第一个要点是只对常规的旧宏进行打折,因此我不得不开始研究程序宏。 本质上具有额外逻辑的宏可以在编译过程中引入,并实际上更改代码的AST。
程序宏是特殊的野兽,因此,首先,我需要声明我的代码是Cargo.toml
文件中的特殊雪花:
[lib]
proc-macro = true
我还提供了一些方便的花花公子包,用于从人类代码(oxymoron?)转换为生锈的AST,然后再次返回syn
和quote
:
syn = "0.13.1"
quote = "0.5.1"
接下来,我启动了实际宏的代码。 这里要做出的重要区别是不同类型的过程宏之间的区别。 我将其留在这里,因为有人已经在Rust Rust Arts的书: The Unstable Book中为我完成了工作。
长话短说-我决定制作一个自定义派生程序宏! 这意味着我的代码看起来像这样开始:
至此,我有一种方法可以将自定义实现添加到结构中,而这正是您要为其使用派生的对象。 很好,但是我仍然希望能够从文件中加载模板。 问题是,在世界范围内如何获取要加载的模板的名称?
好吧,对我们来说幸运的是,我们在编译器领域(比Candy Land更糟糕),因此我们还可以添加额外的属性。 这是带有添加的TemplateName
属性的代码,用于获取模板
是的,我知道顶部有点乱。 就像我的车库和我的办公桌在工作一样,我会在有空的时候去清理它。 我在这里所做的是遍历传递的结构上的属性,以便找到TemplateName
属性。 然后,我基于该字符串加载文件的内容,并将其传递到我们用quote!
令牌流中quote!
。
最后一步是进行实际的内插,虽然有点混乱,但操作起来相对简单。 要记住的重要一点是,从quote!
传回的内容之外的所有内容quote!
将在编译时完成,反之亦然。 请注意,上面的示例实际上并未包含插值,而是指向GitHub上已发布包的源的链接 。
您已经完成了。 您遵循了我分散的逻辑,并用强硬的言辞将最终的表情从纳粹的脸上融化了(您不认为我在第一段中就忘记了印第安纳·琼斯的提法,对吗?)锈; 它们具有安全卫生的类型,但不是灵丹妙药。 它们对于开发人员的安全以及任何必须维护您的代码的人的理智具有有限的力量。 但是,如果有一个在编译时可以确定的问题,那么它们是一个很好的工具。
您可以在以下位置找到代码: https : //github.com/trezm/fuel-line以及此处的合适货物包装: https : //crates.io/crates/fuel_line和此处: https : //crates.io/crates/ fuel_line_derive 。
翻译自: https://hackernoon.com/fast-and-simple-rendering-in-rust-using-proc-macros-f0d919eb6475
磁盘使用 proc