当前位置:网站首页>[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_eqThere 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:exprThe meaning of :
exprIs 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 $xIs 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 au32Literal , Represents the current line ( from 1 Start )column!(): Expand to au32Literal , 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 withCargoUse 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 .
rustcIt can show the information of the code after extending all macros .
cargo build --verboseYou can seeCargoHow to callrustc.- That is, copy
rustccommand , Add again-Z unstable-options --pretty expandedOptions .
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 … exprexpression : 2 + 2, "udon", x.len()=> , ;stmtExpression or declaration , Do not include the semicolon at the end ( priority of use exprorblock)=> , ;tytype : String、Vec<u8>、(&str, bool)=> , ; =pathroute : ferns、::std::sync::mpsc=> , ; =patPattern : _、Some(ref x)=> , =itemCharacteristic item : struct Point {x: f64, y: f64}、mod ferns;There is no limit blockCode block : s += "ok\n"; trueThere is no limit metaAttribute body : inline、derive(Copy, Clone)、doc="3D models."There is no limit identidentifier : std、Json、longish_variable_nameThere is no limit ttToken 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
边栏推荐
- Four logs of MySQL server layer
- How to choose PLC and MCU?
- Prototype design
- Exness foreign exchange: the governor of the Bank of Canada said that the interest rate hike would be more moderate, and the United States and Canada fell slightly to maintain range volatility
- 3857 Mercator coordinate system converted to 4326 (WGS84) longitude and latitude coordinates
- Some problem records of AGP gradle
- 多态day02
- C # create self host webservice
- Analyze menu analysis
- js 正则过滤和增加富文本中图片前缀
猜你喜欢

The real machine cannot access the shooting range of the virtual machine, and the real machine cannot Ping the virtual machine

深入探究指针及指针类型

Codeworks 5 questions per day (1700 average) - day 6

Résumé des méthodes de reconnaissance des caractères ocr

MySQL advanced notes

XSS challenges bypass the protection strategy for XSS injection

Derivation of anti Park transform and anti Clarke transform formulas for motor control

ESBuild & SWC浅谈: 新一代构建工具

Performance test method of bank core business system

Web security SQL injection vulnerability (1)
随机推荐
Selenium share
js 正则过滤和增加富文本中图片前缀
JS音乐在线播放插件vsPlayAudio.js
IPv6 jobs
Quartz misfire missed and compensated execution
How to choose PLC and MCU?
Mysqldump data backup
Leetcode problem solving -- 108 Convert an ordered array into a binary search tree
建模规范:命名规范
Tomb. Weekly update of Finance (February 7 - February 13)
[Li Kou] the second set of the 280 Li Kou weekly match
Erreur de la carte SD "erreur - 110 whilst initialisation de la carte SD
Tidb ecological tools (backup, migration, import / export) collation
3857墨卡托坐标系转换为4326 (WGS84)经纬度坐标
蓝色样式商城网站页脚代码
[padding] an error is reported in the prediction after loading the model weight attributeerror: 'model' object has no attribute '_ place‘
多态day02
JS regular filtering and adding image prefixes in rich text
Pytorch基础——(1)张量(tensor)的初始化
Performance analysis of user login TPS low and CPU full