最近在做一个小项目,作为对rust的应用尝试。web小应用。
例子,也是仿照网上别人的demo做的。web框架用的是warp。在别人的代码里,他用到了宏,照着例子,我也是用宏。
在main.rs里,我是直接引用那个宏,他是把宏再封装在一个server.rs的模块里,在main.rs里引用这个server模块。我想,再封装一层,麻烦了,再说,我现在这个小应用,其实就只有一个url请求,没他那么多,所以就不封装了,在main.rs里直接引用宏。
问题来了,我在编译时,一直报找不到route模块里的函数。这个事,苦恼我很长很长时间,一个月了,还找不到原因(其间有别的事要忙,也没全身心放在这)。
因为我跟原作者的代码没什么区别,我在想,原作者只是封装了一层,他就能跑起来,为啥我不封装那层,我就跑不起来。只好妥协,还是像他那样再封装一层吧,看看我的代码能不能跑起来。于是像模像样的,跟他保持一致,再封装了一层。
果然出乎意料,我的代码也跑起来了,这让我百思不得其解,为啥啊!!仔细做了对比,他所在的server.rs里在引用模块时没有mod,只有use,use了对应的模块。
我们都在main.rs里有mod了相应的模块的。
这再一次让我百思不解,为何这样能正常跑起来的。这一天又过去了,确实也还没想明白。
到了晚上,洗澡时,脑子一下子想明白了。所谓宏,宏是写rust代码的代码,跟函数是有区别的,由于宏是写rust代码的代码,所有教程都说宏在编译期是会展开的。它会展开的,展开的。。。。这下我明白了!!!
宏会展开,它跟函数的区别就在这,它展开后,在它所在的位置里生成了代码,它不是函数,在运行到它的位置时,进入函数里的代码。自己一直以来思维里都隐隐约约的以为当运行到宏的位置时,它像函数一样进入函数里面的代码继而接着执行。
由于它是在编译期展开,在它所在的位置生成代码,因为我的main.rs里只是mod了它需要的模块,没有use,所以编译器告诉我它找不到route里面的函数,因为原作者的server.rs里是有use它所需的模块的。这下我就明白了。
经过这个事实,宏是编译期展开,函数是运行时进入。这个思维转变很重要,非常重要,终于明白宏与函数的区别!!!!
所以,都说学rust有一个陡峭的学习过程,而且有别的语言基础的会发生思维转变。果然是这样啊!!!
记录一下自己的思考过程,至于代码就不贴了,因为是一个很蠢的过程
相关资料
https://dev.to/steadylearner/how-to-use-rust-warp-web-framework-2b4e 原作者的小例子
网友评论