当前位置:网站首页>[rust notes] 18 macro
[rust notes] 18 macro
2022-07-06 03:19:00 【phial03】
18 - macro
assert_eq!
macro : An error message containing the assertion file name and line number can be generated .macro : Is a way to extend the language . During compilation , Before checking the type and generating any machine code , Every macro call will be extended (expanded).
assert_eq!(gcd(6, 10), 2); // The code after the above macro expansion match (&gcd(6, 10), &2) { (left_val, right_val) => { if !(*left_val == *right_val) { panic!("assertion failed: '(left == right)', \ (left: '{:?}', rigth: '{:?}')", left_val, right_val); } } }
Rust Macros can be integrated with other components of the language , Not easy to make mistakes .
- Macro calls are always marked with an exclamation point , Not easy to be ignored .
- Rust Macros will never insert mismatched square brackets or parentheses .
- Rust Macro built-in pattern matching , Easy to maintain and extend .
18.1 - Macro Foundation
macro_rules!
yes Rust The main way of defining macro .marcro_rule! assert_eq { ($left: expr, $right: expr) => ( // Pattern { // Templates match (&$left, &$right) { if !(*left_val == *right_val) { panic!("assertion failed: '(left == right)' \ (left: '{:?}', right: '{:?}')", left_val, right_val) } } } ); }
- Note that in the above code
assert_eq
There is no exclamation point behind . - Exclamation marks are required only when calling macros
!
, When defining, you don't need .
- Note that in the above code
file!
、line!
andmacro_rules!
, Itself is built into the compiler .Another way of macro definition : Procedure macro (procedural macro).
macro_rule!
The macro defined is completely based on the pattern matching implementation logic .( Pattern 1 ) => ( Templates 1 ); ( Pattern 2 ) => ( Templates 2 ); ...
You can use parentheses around patterns and templates , Use square brackets or curly braces .
The following forms are equivalent :
assert_eq!(gcd(6, 10), 2); assert_eq![gcd(6, 10), 2]; assert_eq!{ gcd(6, 10), 2} // When using curly braces , The last semicolon is optional .
Usage conventions or conventions of brackets :
- Calling
assert_eq!
when , Use parentheses - Calling
vec!
Use square brackets - Calling
macro_rules!
Use curly braces
- Calling
18.1.1 - Macro Extension Foundation
You cannot call a macro before defining it ,Rust Macro calls are analyzed and extended .
Macro mode operates on tokens (token), Such as digital 、 name 、 Punctuation, etc Rust Grammatical symbols of programs . Notes and whitespace are not notations .
For
$left:expr
The meaning of :
expr
Is an expression , Its value will be assigned to$left
.- Macro patterns are the same as regular expressions , Only a few special characters trigger special matching behavior .
- Other characters , Like a comma , Need to match literally , Otherwise, matching will fail .
18.1.3 - repeat
The standard
vec!
There are two forms of macros :// Repeat a value N Time let buffer = vec![0_u8; 1000]; // A comma separated list of values let numbers = vec!["udon", "ramen", "soba"];
vec!
Implementation of macro :macro_rules! vec { ($elem: expr; $n: expr) => { ::std::vec::from_elem($elem, $n) }; ( $( $x:expr ),* ) => { <[_]>::into_vec(Box::new([ $( $x ),* ])) }; ( $( $x:expr ),+ ,) => { vec![ $( $x ),* ] }; }
Repetitive patterns :
Pattern meaning $( ... )*
matching 0 Or many times , There is no separator $( ... ),*
matching 0 Or many times , Separated by commas $( ... );*
matching 0 Or many times , Semicolon separated $( ... )+
matching 1 Or many times , There is no separator $( ... ),+
matching 1 Or many times , Separated by commas $( ... );+
matching 1 Or many times , Semicolon separated $x
Is a set of expressions ;<[_]>
A slice that represents a certain type of value .,
Indicates matching a list with extra commas .
18.2 - Built in macro
file!()
: Expand to a string literal , The current file name .line!()
: Expand to au32
Literal , Represents the current line ( from 1 Start )column!()
: Expand to au32
Literal , Represents the current column ( from 0 Start )stringify!(...tokens...)
: Expand to a string literal , Contains the given token .assert!
Use this built-in macro to generate an error message containing assertion code .- If the parameter contains a macro , Then there will be no expansion , Such as
stringify(line!())
, Any parameter is a string"line!()"
.
concat!(str0, str1, ...)
: Expand to a string literal , Is the result of splicing its parameters .cfg!(...)
: Expand to a Boolean constant , If the current build configuration matches the conditions in parentheses , Then fortrue
.env!("VAR_NAME")
: Expand to a string , That is, specify the value of the environment variable at compile time . If the specified variable does not exist , A compilation error occurs . Often withCargo
Use a combination of .option_env!("VAR_NAME")
: Andenv!
identical , But back toOption<&'static str>
, If the specified variable is not set , Then return toNone
.include!("file.rs")
: Expand to the contents of the specified file , Must be effective Rust Code , For example, the sequence of expressions or characteristic items .include_str!("file.txt")
: Expand to a&'static str
, Contains the text of the specified file .Usage method :
const COMPOSITOR_SHADER: &str = include_str!("../resources/compositor.glsl");
If the specified file does not exist , Or the text is not valid UTF-8, Causes a compilation error .
include_bytes!("file.dat")
: Extend the file as binary data . As a result,&'static [u8]
Type value .Rules for built-in macros :
- Processed at compile time , If the file does not exist or cannot be read , Then the compilation will fail .
- All macros cannot fail at run time .
- In any case , If the file name is a relative path , It will be parsed relative to the directory containing the current file .
18.3 - Debug macro
The process of macro expansion is invisible .
- Rust In the process of extending macros , When some errors are found, an error message will be printed .
- But the fully extended code with errors will not be displayed .
rustc
It can show the information of the code after extending all macros .
cargo build --verbose
You can seeCargo
How to callrustc
.- That is, copy
rustc
command , Add again-Z unstable-options --pretty expanded
Options .
log_syntax!()
macro : At compile time , Its parameters can be printed to the terminal .
- Can be used to implement similar
println!
Debugging of . - It is required to have
#![feature(log_syntax)]
Characteristic marks .
- Can be used to implement similar
Give Way Rust The compiler prints the logs of all macro calls to the terminal .
- Insert... Somewhere in the code
trace_macros!(true);
. - such ,Rust Each macro expanded , Will print the name and parameters of the macro .
- Insert... Somewhere in the code
18.4 - Customize a macro ——json!
macro
To develop a json!
macro , Receive one JSON
Value as parameter , Then expand it to something like the following Rust expression :
let students = json!([
{
"name": "Jim Blandy"
"class_of": 1926
"major": "Tibetan throat singing"
},
]);
18.4.1 - Fragment type
macro_rules!
Fragment types supported by macros :Fragment type matching ( Example ) You can add … expr
expression : 2 + 2, "udon", x.len()
=> , ;
stmt
Expression or declaration , Do not include the semicolon at the end ( priority of use expr
orblock
)=> , ;
ty
type : String
、Vec<u8>
、(&str, bool)
=> , ; =
path
route : ferns
、::std::sync::mpsc
=> , ; =
pat
Pattern : _
、Some(ref x)
=> , =
item
Characteristic item : struct Point {x: f64, y: f64}
、mod ferns;
There is no limit block
Code block : s += "ok\n"; true
There is no limit meta
Attribute body : inline
、derive(Copy, Clone)
、doc="3D models."
There is no limit ident
identifier : std
、Json
、longish_variable_name
There is no limit tt
Token tree : ;
、>=
、{}
、[0 1 (+ 0 1)]
There is no limit json!
The definition of macro is as follows :macro_rules! json { (null) => { Json::Null }; ([ $( $element:tt ),* ]) => { Json::Array(...) }; ({ $( $key:tt : $value:tt ),* }) => { Json::Object(...) }; ($other:tt) => { ... // TODO: return Number、String or Boolean }; }
18.6 - transcend macro_rules!
- Procedure macro :
- Support extended
#[derive]
attribute , To handle custom features . - As Rust Function implementation , Not a declarative rule set .
- Support extended
See 《Rust Programming 》( Jim - Brandy 、 Jason, - By orendov , Translated by lisongfeng ) Chapter 20
Original address
边栏推荐
- Modeling specifications: naming conventions
- Résumé des méthodes de reconnaissance des caractères ocr
- Who is the winner of PTA
- Four logs of MySQL server layer
- Custom attribute access__ getattribute__/ Settings__ setattr__/ Delete__ delattr__ method
- 银行核心业务系统性能测试方法
- 电机控制反Park变换和反Clarke变换公式推导
- 【SLAM】lidar-camera外参标定(港大MarsLab)无需二维码标定板
- [concept] Web basic concept cognition
- [ruoyi] enable Mini navigation bar
猜你喜欢
Era5 reanalysis data download strategy
SAP ALV颜色代码对应颜色(整理)
NR modulation 1
Map sorts according to the key value (ascending plus descending)
How to choose PLC and MCU?
[risc-v] external interrupt
Huawei, H3C, Cisco command comparison, mind map form from the basic, switching, routing three directions [transferred from wechat official account network technology alliance station]
The real machine cannot access the shooting range of the virtual machine, and the real machine cannot Ping the virtual machine
记录一下逆向任务管理器的过程
Overview of OCR character recognition methods
随机推荐
canvas切积木小游戏代码
Self made CA certificate and SSL certificate using OpenSSL
【paddle】加载模型权重后预测报错AttributeError: ‘Model‘ object has no attribute ‘_place‘
Problems encountered in 2022 work IV
教你用Pytorch搭建一个自己的简单的BP神经网络( 以iris数据集为例 )
Cross origin cross domain request
Restful style
[pointer training - eight questions]
Image super-resolution using deep convolutional networks(SRCNN)解读与实现
2022工作中遇到的问题四
电机控制反Park变换和反Clarke变换公式推导
My C language learning records (blue bridge) -- files and file input and output
继承day01
深入探究指针及指针类型
Is there a completely independent localization database technology
Software design principles
Who is the winner of PTA
codeforces每日5题(均1700)-第六天
How to do function test well
These are not very good