最近在做一個(gè)小項(xiàng)目,作為對(duì)rust的應(yīng)用嘗試。web小應(yīng)用。
例子,也是仿照網(wǎng)上別人的demo做的。web框架用的是warp。在別人的代碼里,他用到了宏,照著例子,我也是用宏。
在main.rs里,我是直接引用那個(gè)宏,他是把宏再封裝在一個(gè)server.rs的模塊里,在main.rs里引用這個(gè)server模塊。我想,再封裝一層,麻煩了,再說(shuō),我現(xiàn)在這個(gè)小應(yīng)用,其實(shí)就只有一個(gè)url請(qǐng)求,沒(méi)他那么多,所以就不封裝了,在main.rs里直接引用宏。
問(wèn)題來(lái)了,我在編譯時(shí),一直報(bào)找不到route模塊里的函數(shù)。這個(gè)事,苦惱我很長(zhǎng)很長(zhǎng)時(shí)間,一個(gè)月了,還找不到原因(其間有別的事要忙,也沒(méi)全身心放在這)。
因?yàn)槲腋髡叩拇a沒(méi)什么區(qū)別,我在想,原作者只是封裝了一層,他就能跑起來(lái),為啥我不封裝那層,我就跑不起來(lái)。只好妥協(xié),還是像他那樣再封裝一層吧,看看我的代碼能不能跑起來(lái)。于是像模像樣的,跟他保持一致,再封裝了一層。
果然出乎意料,我的代碼也跑起來(lái)了,這讓我百思不得其解,為啥?。。∽屑?xì)做了對(duì)比,他所在的server.rs里在引用模塊時(shí)沒(méi)有mod,只有use,use了對(duì)應(yīng)的模塊。
我們都在main.rs里有mod了相應(yīng)的模塊的。
這再一次讓我百思不解,為何這樣能正常跑起來(lái)的。這一天又過(guò)去了,確實(shí)也還沒(méi)想明白。
到了晚上,洗澡時(shí),腦子一下子想明白了。所謂宏,宏是寫rust代碼的代碼,跟函數(shù)是有區(qū)別的,由于宏是寫rust代碼的代碼,所有教程都說(shuō)宏在編譯期是會(huì)展開(kāi)的。它會(huì)展開(kāi)的,展開(kāi)的。。。。這下我明白了?。。?/p>
宏會(huì)展開(kāi),它跟函數(shù)的區(qū)別就在這,它展開(kāi)后,在它所在的位置里生成了代碼,它不是函數(shù),在運(yùn)行到它的位置時(shí),進(jìn)入函數(shù)里的代碼。自己一直以來(lái)思維里都隱隱約約的以為當(dāng)運(yùn)行到宏的位置時(shí),它像函數(shù)一樣進(jìn)入函數(shù)里面的代碼繼而接著執(zhí)行。
由于它是在編譯期展開(kāi),在它所在的位置生成代碼,因?yàn)槲业膍ain.rs里只是mod了它需要的模塊,沒(méi)有use,所以編譯器告訴我它找不到route里面的函數(shù),因?yàn)樵髡叩膕erver.rs里是有use它所需的模塊的。這下我就明白了。
經(jīng)過(guò)這個(gè)事實(shí),宏是編譯期展開(kāi),函數(shù)是運(yùn)行時(shí)進(jìn)入。這個(gè)思維轉(zhuǎn)變很重要,非常重要,終于明白宏與函數(shù)的區(qū)別?。。?!
所以,都說(shuō)學(xué)rust有一個(gè)陡峭的學(xué)習(xí)過(guò)程,而且有別的語(yǔ)言基礎(chǔ)的會(huì)發(fā)生思維轉(zhuǎn)變。果然是這樣?。。?!
記錄一下自己的思考過(guò)程,至于代碼就不貼了,因?yàn)槭且粋€(gè)很蠢的過(guò)程
相關(guān)資料
https://dev.to/steadylearner/how-to-use-rust-warp-web-framework-2b4e 原作者的小例子