что такое procedural map в расте
The Rust Reference
Procedural Macros
Procedural macros allow creating syntax extensions as execution of a function. Procedural macros come in one of three flavors:
Procedural macros allow you to run code at compile time that operates over Rust syntax, both consuming and producing Rust syntax. You can sort of think of procedural macros as functions from an AST to another AST.
Note: When using Cargo, Procedural macro crates are defined with the proc-macro key in your manifest:
As functions, they must either return syntax, panic, or loop endlessly. Returned syntax either replaces or adds the syntax depending on the kind of procedural macro. Panics are caught by the compiler and are turned into a compiler error. Endless loops are not caught by the compiler which hangs the compiler.
Procedural macros run during compilation, and thus have the same resources that the compiler has. For example, standard input, error, and output are the same that the compiler has access to. Similarly, file access is the same. Because of this, procedural macros have the same security concerns that Cargo’s build scripts have.
Procedural macros have two ways of reporting errors. The first is to panic. The second is to emit a compile_error macro invocation.
The proc_macro crate
Procedural macro crates almost always will link to the compiler-provided proc_macro crate. The proc_macro crate provides types required for writing procedural macros and facilities to make it easier.
Procedural macro hygiene
Procedural macros are unhygienic. This means they behave as if the output token stream was simply written inline to the code it’s next to. This means that it’s affected by external items and also affects external imports.
Macro authors need to be careful to ensure their macros work in as many contexts as possible given this limitation. This often includes using absolute paths to items in libraries (for example, ::std::option::Option instead of Option ) or by ensuring that generated functions have names that are unlikely to clash with other functions (like __internal_foo instead of foo ).
Function-like procedural macros
For example, the following macro definition ignores its input and outputs a function answer into its scope.
And then we use it in a binary crate to print «42» to standard output.
Function-like procedural macros may be invoked in any macro invocation position, which includes statements, expressions, patterns, type expressions, item positions, including items in extern blocks, inherent and trait implementations, and trait definitions.
Derive macros
Derive macros define new inputs for the derive attribute. These macros can create new items given the token stream of a struct, enum, or union. They can also define derive macro helper attributes.
The input TokenStream is the token stream of the item that has the derive attribute on it. The output TokenStream must be a set of items that are then appended to the module or block that the item from the input TokenStream is in.
And then using said derive macro:
Derive macro helper attributes
Derive macros can add additional attributes into the scope of the item they are on. Said attributes are called derive macro helper attributes. These attributes are inert, and their only purpose is to be fed into the derive macro that defined them. That said, they can be seen by all macros.
The way to define helper attributes is to put an attributes key in the proc_macro_derive macro with a comma separated list of identifiers that are the names of the helper attributes.
And then usage on the derive macro on a struct:
Attribute macros
Attribute macros define new outer attributes which can be attached to items, including items in extern blocks, inherent and trait implementations, and trait definitions.
For example, this attribute macro takes the input stream and returns it as is, effectively being the no-op of attributes.
This following example shows the stringified TokenStream s that the attribute macros see. The output will show in the output of the compiler. The output is shown in the comments after the function prefixed with «out:».