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

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

rust開發(fā)web項(xiàng)目附錄一——簡(jiǎn)單的proc macro教程

2023-02-22 14:36 作者:pathologyenigma  | 我要投稿

鑒于我們需要在irmin上層編寫數(shù)據(jù)管理相關(guān)的功能,而此類功能為了方便用戶也為了高效性,自是繞不開proc macro,由于在下自己對(duì)proc macro亦是使用多過編寫,這里便從頭開始編寫一篇proc macro的教程,本文主要參考的資料均為社區(qū)久負(fù)盛名的文檔,如果各位觀看完之后仍深感疑惑,那說明在下的水平有很大問題,與引用的資料無關(guān)(疊甲,過)

官方文檔對(duì)proc macro的解釋是,讓你可以在編譯期執(zhí)行操作rust語法的代碼,既可以消耗掉rust代碼,也可以生成rust代碼,可以理解為一個(gè)作用于AST(抽象語法樹)的函數(shù)

從以上描述可以大概猜測(cè)proc macro在編譯的哪一步執(zhí)行(不知道的自行補(bǔ)充一下編譯原理的知識(shí)),整體來說可以簡(jiǎn)單的理解為在編譯期對(duì)代碼生成的抽象語法樹進(jìn)行修改

可能很抽象,但是沒關(guān)系,我們一點(diǎn)一點(diǎn)來了解,首先來創(chuàng)建一個(gè)用于學(xué)習(xí)proc macro的項(xiàng)目,注意要開啟proc macro

然后,最基本的proc macro可以是一個(gè)簡(jiǎn)單的編譯期函數(shù)(注意,此場(chǎng)景下不如直接編寫另一種宏來的方便快捷)

proc macro 不能在創(chuàng)建的庫使用,故而本文的測(cè)試將有單獨(dú)的一個(gè)項(xiàng)目來負(fù)責(zé),這里為了閱讀體驗(yàn)就不涉及對(duì)應(yīng)項(xiàng)目的創(chuàng)建了

測(cè)試一下:

沒有什么問題

那么,實(shí)際上這里的宏寫起來有點(diǎn)像D語言的mixin,但顯然如果只是用字符串的話,那可算不上方便,但我們現(xiàn)在還是新手,得先了解proc macro本身,之后再去進(jìn)階

那么,接下來了解重點(diǎn),derive macro和attribute?macro,首先還是一樣的是接收Token Stream,返回TokenStream的函數(shù)

注意,這里我們只是使用derive macro創(chuàng)建了一個(gè)函數(shù),并沒有干別的事情,而且該函數(shù)并不會(huì)成為這個(gè)struct的成員或怎么樣,只是單純的添加了一個(gè)函數(shù)

那么,將測(cè)試修改為:

依舊會(huì)得到hello world(這里rust analyser可能會(huì)報(bào)錯(cuò),但實(shí)際上并無錯(cuò)誤)

然后是作為derive macro的一部分的attribute macro,大家多少都用過,我也就不多說了,這里直接寫一下例子

這里定義了一個(gè)無意義的attribute宏,該類型的宏的主要作用是用來做標(biāo)記

由于該宏沒有任何意義,這里就不追加測(cè)試了(浪費(fèi)鍵盤耐久度)

另一種attribute macro則有所不同,該macro接收兩個(gè)參數(shù)一個(gè)是括號(hào)內(nèi)的參數(shù),一個(gè)是被derive的對(duì)象,該macro與derive目的一致,但效果略有不同

到這里為止,rust reference便無更多有意義的參考了,例如TokenStream是個(gè)怎樣的類型(作為一個(gè)容器類型,表明上看不出具體的存儲(chǔ)方式和可能的值),我們?nèi)绾胃奖愕奶峁┳鳛榉祷刂档腡okenStream,此時(shí)就需要參考一些其他的文檔

而rust book則稍微提供了一些,之所以將這個(gè)置于rust reference之后,主要原因是該內(nèi)容沒有對(duì)derive macro做基本的介紹和解釋,便直接開始引用syn和quote庫進(jìn)行編寫,雖然也能行得通,但未免太過跳躍

那么,我們便引入syn和quote

這里我們并未對(duì)feature進(jìn)行篩選,主要原因是在下對(duì)這兩個(gè)庫了解并不多,不敢冒然修改feature

那么,接下來,我們假設(shè)我們有一個(gè)trait需要通過derive宏來提供默認(rèn)的基于struct本身成員的實(shí)現(xiàn),但開始之前我們得先對(duì)這兩個(gè)庫有點(diǎn)基本的了解

那么,老規(guī)矩,cargo doc?--open

然后我們可以看到我們此時(shí)依賴的crate之中甚至還有個(gè)proc-macro2(其實(shí)和proc-macro并非版本更新的關(guān)系)

那么從這個(gè)庫的文檔開始看起,首先該庫是上述我們提到的兩個(gè)庫中syn的依賴項(xiàng),該庫在官方標(biāo)準(zhǔn)的proc-macro的上層,但支持從proc-macro的TokenStream到其自己的TokenStream之間相互轉(zhuǎn)換,倒也不算麻煩,這里我們主要了解一下這個(gè)庫提供的一些類型,例如,Ident之類的,這些對(duì)我們后續(xù)解析宏和上下文中的其他東西大有幫助

該庫提供的所有類型,這里所有的英文單詞都是基礎(chǔ)單詞或者行業(yè)內(nèi)的專有名詞,想必應(yīng)該用不著翻譯

然后我來看quote,quote這個(gè)庫提供了一些工具用于將rust語法轉(zhuǎn)換為TokenStream,使得用戶在編寫derive宏的時(shí)候可以使用類似macro_rule的方式,以下是該庫提供的宏和traits:

同樣很基礎(chǔ)的英文,應(yīng)當(dāng)也是無需翻譯的(對(duì)吧)

最后是syn,之所以將其放在最后,是該庫依賴于上述兩個(gè)庫,加之其本身也比另外兩個(gè)庫復(fù)雜許多

但該庫使用起來卻并不復(fù)雜,由于其本身是TokenStream到語法樹的轉(zhuǎn)換庫,故而其上層api主要為此服務(wù)

這里我們并不需要深入學(xué)習(xí)該庫,只需要其提供的解析derive input的功能即可

首先一個(gè)常規(guī)的proc-macro也許長(zhǎng)這樣:

這里用到了DeriveInput類型,我們簡(jiǎn)單看一下這個(gè)類型定義:

簡(jiǎn)單直白,想必也不需要在下翻譯

此時(shí)我們可以把之前的hello_world macro修改成下面這樣:

此時(shí),該宏將為對(duì)應(yīng)類型實(shí)現(xiàn)一個(gè)hello world trait(注意,由于proc-macro開啟的庫是無法聲明公開的trait的,所以,我們需要定義在別的的地方,這里的實(shí)現(xiàn)部分在當(dāng)前庫沒有定義trait的情況下依然可用,你自己清楚你的trait的標(biāo)準(zhǔn)即可),然后測(cè)試一下:

依舊還是hello world

那么其他的macro形式也類似,再牛逼的庫的derive功能也都是這些簡(jiǎn)單的宏構(gòu)成的,各位多練習(xí)應(yīng)當(dāng)就能達(dá)成自己的使用要求了

rust reference的proc macro相關(guān)文檔:https://doc.rust-lang.org/reference/procedural-macros.html#procedural-macros

rust official book的相關(guān)文檔:https://doc.rust-lang.org/book/ch19-06-macros.html

最后推薦還想進(jìn)一步了解的各位可以去看一下大佬的庫,例如serde


rust開發(fā)web項(xiàng)目附錄一——簡(jiǎn)單的proc macro教程的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
银川市| 高尔夫| 南阳市| 黑河市| 永泰县| 凉城县| 夏河县| 中牟县| 和林格尔县| 沅陵县| 莱阳市| 天祝| 凯里市| 江永县| 博客| 田阳县| 泰顺县| 邢台县| 武乡县| 长宁县| 同德县| 扶沟县| 平顺县| 永州市| 赤峰市| 大足县| 晋州市| 化隆| 宁陵县| 中西区| 邵武市| 葵青区| 屏东市| 胶南市| 梅州市| 沁源县| 新宾| 安塞县| 屯门区| 仁布县| 精河县|