最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

Rust 過程宏(第二彈)

2022-12-17 14:59 作者:緊果唄  | 我要投稿

## ? Rust Macros 宏編程

  • [The Little Book of Rust Macros](https://veykril.github.io/tlborm/)
  • [The Little Book of Rust Macros](https://danielkeep.github.io/tlborm/book/index.html)
  • [Introduction to Procedural Macros in Rust](https://tinkering.xyz/introduction-to-proc-macros/)
  • [Procedural Macros in Rust 2018](https://blog.rust-lang.org/2018/12/21/Procedural-Macros-in-Rust-2018.html)
  • [3.2. Procedural Macros](https://doc.rust-lang.org/reference/procedural-macros.html)
  • https://doc.rust-lang.org/rust-by-example/macros.html
  • https://doc.rust-lang.org/book/ch19-06-macros.html
  • https://doc.rust-lang.org/stable/reference/attributes.html#active-and-inert-attributes
  • https://docs.rs/json/0.12.4/json/
  • https://github.com/Jeangowhy/Godot-Tour


首先,不像 C/C++ 的宏定義,只是簡單的代碼預(yù)處理程序,用宏代碼替換一下部分源代碼。Rust 的宏具有相當(dāng)復(fù)雜的功能,更貼近編譯器的語法樹處理。


簡單地說,Rust 宏就是內(nèi)嵌的 DSL - Domain Specific Languages 可以讓你可以發(fā)明自己的語法,編寫出可以自行展開的代碼,并且還可以實現(xiàn)靜態(tài)反射功能。


宏的應(yīng)用是符合 DRY (Don't Repeat Yourself) 軟件工程原理的,有輪子的車就讓它跑,沒有必要重新造輪子,Don't write DRY code!


Rust 作為靜態(tài)編譯型語言,rustc 編譯器本身由 Rust 語言實現(xiàn),即實現(xiàn)了自舉,后端部分則基于現(xiàn)成的 LLVM。


Rust 編譯器簡要工作流程如下:


  • 首先,讀取源代碼做 Tokens 掃描,得到 Token stream 數(shù)據(jù),這部分程序也叫做 Syntax Analyzer;
  • 然后對源碼進(jìn)行詞法分析得到 Abstract Syntax Tree (AST) 抽像語法樹,這部分程序叫做 Parser;
  • 再將 AST 轉(zhuǎn)換為 High-Level IR (HIR) 以便做類型推斷、trait 接口處理以及靜態(tài)類型安全性檢查;
  • 再轉(zhuǎn)換為 Mid-level IR (MIR) 以便做所有權(quán)借用檢查和代碼優(yōu)化,MIR 也是 Control-Flow Graph (CFG);
  • 經(jīng)過以上前端工作后,代碼會轉(zhuǎn)譯為 LLVM IR,文件后綴一般是 .ll,是文本格式,字節(jié)碼文件后綴是 .bc;
  • 得到中間代碼表達(dá),下一步就是生成相應(yīng)的機器碼,這就是 LLVM 要做的工作。


通過 `macro_rules` 關(guān)鍵字定義的一系列規(guī)則,在調(diào)用宏時,編譯器會先匹配規(guī)則,匹配中的 $expansion 才被展開。


除了使用 `macro_rules` 關(guān)鍵字定義宏規(guī)則,Rust 有三種宏程序:


- Function-like macros - `custom!(...)` 使用 `#[proc_macro]` 定義;

- Derive macros - `#[derive(CustomDerive)]` 使用 `#[proc_macro_derive]` 定義;

- Attribute macros - `#[CustomAttribute]` 使用 `#[proc_macro_attribute]` 定義;


宏程序使用 Cargo new --lib 命令創(chuàng)建一個庫,并且指定 proc-macro 類型,這樣才能夠使用過程宏:


??[lib]

??proc-macro = true


??[dependencies]

??quote = "1.0"

??syn = "1.0"

??proc-macro2 = "1.0"



宏程序與函數(shù)的區(qū)別在于后綴的感嘆號:


```rust,ignore

macro_rules! $name {

??($pattern) => {$expansion}; // $rule0 ;

??($pattern) => {$expansion}; // $rule1 ;

??($pattern) => {$expansion}; // ...

??($pattern) => {$expansion}; // $ruleN ;

}

```


宏至少定義一條規(guī)則,最后一條規(guī)則的分號可省略。


列如,有以下這樣一個宏定義:


??macro_rules! four {

????() => {1 + 3};

??}


調(diào)用宏時,編譯器會匹配到輸入為空的條件,包括 `four!()`, `four![]` or `four!{}` 這幾種調(diào)用形式。

很有必要從編譯器語法樹構(gòu)建原理的角度來解析宏的概念。


Rust 系統(tǒng)中有許多類型的 Tokens:


  • Identifiers: foo, Bambous, self, we_can_dance, LaCaravane, …
  • Integers: 42, 72u32, 0_______0, …
  • Keywords: _, fn, self, match, yield, macro, …
  • Lifetimes: 'a, 'b, 'a_rare_long_lifetime_name, …
  • Strings: "", "Leicester", r##"venezuelan beaver"##, …
  • Symbols: [, :, ::, ->, @, <-, …


這些會出現(xiàn)在代碼中的 Tokens 經(jīng)過編譯器初步處理,就會轉(zhuǎn)換成 AST - Abstract Syntax Tree,Token trees 則是介于 Tokens 與 AST 之間的東西。以樹狀數(shù)據(jù)結(jié)構(gòu)方式存放,所以叫做語法樹。


將源代碼的字符流轉(zhuǎn)換成 Token 是編譯原理最開始的部分,做這一步工作的程序叫做 Lexical Analyzer 詞法分析器,然后將源代碼中字符串中的 Tokens 轉(zhuǎn)換為 AST,這一步對應(yīng)的程序叫做 Syntax Analyzer,即詞法解析器 Parser。


編寫過程宏,通常需要借助三個 crate 來解析語法樹中的節(jié)點數(shù)據(jù):


  1. syn 模塊用來解析語法樹(AST)的各種語法構(gòu)成,即是 Syntax Analyzer。
  2. quote 解析語法樹,生成 Rust 代碼,從而實現(xiàn)想要的功能。
  3. proc_macro(std) 和 proc_macro2(3rd-party)

例如,以下是使用 `println!("{input:#?}");` 打印 `2, 2` 這個表達(dá)式對應(yīng)的 TokenStream 對象:


示范:創(chuàng)建一個庫 hello_macro_derive,并配置依賴,還有設(shè)置庫類型為 proc-macro,即一個宏庫:


??[lib]

??proc-macro = true


??[dependencies]

??syn = "0.14.4"

??quote = "0.6.3"


然后在 hello_macro_derive/lib.rs 文件中自定義宏的功能實現(xiàn)。


編寫自定義宏使用的注解是 `#[proc_macro_derive(HelloMacro)]`,其中 HelloMacro 是宏的名稱,使用可繼承宏時,只需要使用注解 `#[derive(HelloMacro)]` 即可。


在使用時我們應(yīng)該先引入這個依賴


??hello_macro_derive = { path = "../hello_macro_derive" }


然后再來使用,這里定義一個 trait 名字 HelloMacro 和方法名對應(yīng)上面 quote! 宏定義的內(nèi)容相匹配:

通過 HelloMacro 可繼承宏,Pancakes 這個結(jié)構(gòu)體便自動實現(xiàn)了 hello_macro() 這個接口方法。


Rust 過程宏(第二彈)的評論 (共 條)

分享到微博請遵守國家法律
那坡县| 定结县| 沾化县| 盐山县| 遵义市| 阳朔县| 武隆县| 保康县| 新蔡县| 舞阳县| 资兴市| 松滋市| 安福县| 正镶白旗| 黑水县| 合川市| 浦东新区| 孟津县| 南陵县| 夏邑县| 通海县| 兰考县| 普定县| 灌南县| 平潭县| 诸城市| 婺源县| 海宁市| 安图县| 赤城县| 垫江县| 措美县| 喀什市| 泰和县| 湖口县| 白山市| 泸州市| 廊坊市| 静海县| 周宁县| 武乡县|