有哪些类型的宏/语法扩展/编译器插件? [英] What types of Macros/Syntax Extensions/Compiler Plugins are there?

查看:56
本文介绍了有哪些类型的宏/语法扩展/编译器插件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Rust生态系统中的一些类似于宏的事物所使用的许多术语使我感到非常困惑.有人可以澄清一下其中有哪些宏/语法扩展/编译器插件,并解释这些术语之间的关系吗?

I am very confused by the many terms used for several macro-like things in the Rust ecosystem. Could someone clarify what macros/syntax extensions/compiler plugins there are as well as explain the relationship between those terms?

推荐答案

您是对的:它令人困惑.特别是,因为这些功能大多数都是不稳定的,并且经常更改.但是,我将尝试总结当前的情况( 2016年12月).

You are right: it is confusing. Especially, because most of those features are unstable and change fairly often. But I'll try to summarize the current situation (December 2016).

让我们从语法扩展开始:必须对其进行调用"或手动注释才能生效.三种语法扩展名,其注释方式不同:

Let's start with the Syntax Extension: it's something that has to be "called" or annotated manually in order to have any effect. There are three kinds of syntax extensions, which differ in the way you annotate them:

  • 类似函数的语法扩展名:这些可能是最常见的语法扩展名,也称为宏".调用它们的语法是foo!(…)或(这很少见)foo! some_ident (…),其中foo是宏的名称.请注意,可以将()括号替换为[]{}. 类似函数的语法扩展可以定义为""或"过程宏".

  • function-like syntax extensions: these are probably the most common syntax extensions, also called "macros". The syntax for invoking them is foo!(…) or (and this is pretty rare) foo! some_ident (…), where foo is the macro's name. Note that the () parenthesis can be replaced by [] or {}. Function-like syntax extensions can be defined either as a "macro by example" or as a "procedural macro".

类似属性的语法扩展名:它们像#[foo(…)]一样被调用,其中不需要括号,再次,foo是语法扩展名.然后可以通过其他项目(装饰器)修改或扩展属性所属的项目.

attribute-like syntax extensions: these are invoked like #[foo(…)] where the parenthesis are not necessary and, again, foo is the name of the syntax extension. The item the attribute is belonging to can then be modified or extended by additional items (decorator).

自定义派生:大多数Rust程序员已经使用了#[derive(…)]属性.当然,derive本身可以看作是类似于属性的语法扩展.但是它也可以扩展,然后像#[derive(Foo)]那样被调用,其中Foo自定义派生类的名称.

custom derives: most Rust-programmers have already used the #[derive(…)] attribute. Of course, derive itself can be seen as attribute-like syntax extension. But it can also be extended, which is then invoked like #[derive(Foo)], where Foo is the name of the custom derive.

这些语法扩展中的大多数也是"编译器插件".唯一的例外是类似于函数的语法扩展,它们通过"示例宏"(意为macro_rules!语法)定义.可以在源代码中定义示例宏,而无需编写编译器插件.

Most of these syntax extensions are also "compiler plugins". The only exception are function-like syntax extensions which are defined via "macro by example" (meaning macro_rules! syntax). Macros by example can be defined in your source code without writing a compiler plugin whatsoever.

但是还有编译器插件,它们不是语法扩展.那些 compiler插件类型是linters或其他插件,它们在编译过程的某些阶段运行某些代码.它们不需要手动调用:加载后,编译器将在编译过程中的某些时候调用它们.

But there are also compiler plugins that aren't syntax extensions. Those types of compiler plugins are linters or other plugins which run some code at some stage of the compiling process. They don't need to be invoked manually: once loaded, the compiler will call them at certain points during compilation.

所有编译器插件都必须先通过装箱根目录中的#![plugin(foo)]或使用-Zextra-plugins=too,bar命令行参数进行加载,然后才能生效!

All compiler plugins need to be loaded – either via #![plugin(foo)] at the crate-root or with the -Zextra-plugins=too,bar command line parameter – before they can have any effect!

编译器插件当前不稳定,因此您需要每晚进行编译才能使用它们.但是宏1.1" -RFC 可能很快就会稳定,这意味着编译器插件的一小部分可以与稳定的编译器一起使用.

Compiler plugins are currently unstable, therefore you need a nightly-compiler to use them. But the "Macro 1.1"-RFC will probably be stabilized soon, which means that a small subsets of compiler plugins can then be used with the stable compiler.

有用的链接:

  • Documentation about registering compiler plugins
  • Book Chapter about compiler plugins

这篇关于有哪些类型的宏/语法扩展/编译器插件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆