zoukankan      html  css  js  c++  java
  • Rust 模块系统

    相信不少人和我一样初次接触Rust的模块系统时都会觉得难以理解,因为与之前学的编程语言的文件导入不一样。个人觉得C/C++系的导入是最容易理解的,直接将头文件中定义的内容include后就可以使用其中的内容。

    但是Rust不一样,Rust使用模块 mod 来管理所有的权限和导入问题。在创建了一个微型项目测试一会之后,并结合这篇文章,我总算搞懂了Rust的模块系统。

    当导入文件在同一个文件夹下时

    首先使用 Cargo 创建一个新项目,我这里使用官网教程使用的案例:一个餐厅。一个餐厅分为前后端,前端负责点菜,后端负责做菜。这时项目还不复杂,因此我们直接用两个文件: front.rs 和 back.rs 来代表前后端。

    如果我们想要在 main.rs 使用这两个文件夹中,我们需要创建一个模块,比如想要使用 front.rs 的点菜函数 order

    mod front;
    
    fn main() {
        front::order();
    }
    

    这里注意 front.rs 中的 order 必须是 pub 的。

    你可能会奇怪,为什么 mod front 是写在 main.rs 文件里面的?毕竟按照官网教程的话,front 模块下的所有代码都应定义在 mod front {} 这个括号里面。但是那样的话 front 模块将只能在 front.rs 中使用,而无法导入到其它文件中。或者说需要再在其它文件中另外定义一个包含 front.rs 所有代码的模块,但那是另外一个模块,即便两个模块名字都是 front. 因为编译器不会去推测你的 front.rs 中到底是只有一个 mod front {} 还是有其它代码。

    导入文件夹下的模块

    很多时候用于表示某个功能的代码可能分散到多个文件中,而将这些文件收集到一个文件夹下是一种常见的操作。比如我们将餐厅的后端分散到多个文件中,因为后端包含多个步骤:洗菜,做菜,洗碗等。

    要想让一个文件夹下的所有文件成为一个模块,首先这个文件夹中必须包含一个 mod.rs 文件,类似 node.js 中的 index.js 文件。没有这个文件,即便你在 main.rs 中使用 mod 声明模块编译器也无法找到。

    其次,如果你只想在 mod.rs 中使用其它文件的代码的话,只需要 mod 声明这个模块后即可,就想我们在根目录下做的那样。而如果像高一级路径下使用,必须要经 mod.rs 通过 pub 声明后使用。

    比如在 back 目录下的 wash.rs 表示洗菜,里面有一个洗菜函数 wash. 则在 main.rs 可以这般调用:

    mod back;
    
    fn main() {
        back::wash::wash();
    }
    

    在 back/mod.rs 中声明模块:

    pub mod wash;
    

    在back/wash.rs 声明函数:

    pub fn wash() {
        println!("washing food.");
    }
    

    注意必须是声明为 pub

    调用上一级路径下的文件夹下的模块

    问题又来了,如果我们想要在 front 文件夹下使用 back 文件夹下的代码怎么办呢?

    这时我们就要使用绝对路径,而且光是绝对路径还不行。必须要在 跟路径下的 lib.rs 文件中公共声明要使用 module, 所以我们声明:

    pub mod back;
    

    这样我们就在跟路径下创建了模块 back, 而跟路径下的所有模块都可以被 crate:: 来引用,这就是绝对路径。

    为了避免麻烦,我们可以将这个模块直接带到front中。

    在 front.rs 中:

    use crate::back;
    

    但值得注意的问题是,你不能在根目录下这样使用,不管是对于 main.rs 还是 根目录下的其他文件。比如,在根目录下如果你想要通过 crate::back::wash::wash() 是无法成功调用的。似乎是因为 crate 只对下一级目录可见。Instead, 你必须通过 hello::back::wash::wash(), 其中 hello 是我创建的项目的名字。或者你也可以通过之前讨论的方式调用。

    基本这些就是常见的导入情况了,如果还有遗漏的或者不懂的导入情景可以在评论区补充。

    我愿潇洒如鹰,远离地上宿命
  • 相关阅读:
    数据结构和算法之最大堆
    AStar
    合并SkinnedMeshRender实现换装
    Asp.net MVC 解决:CS0308: 非泛型 方法“System.Web.Mvc.Html.LinkExtensions.ActionLink
    使用jquery解析Json , 浏览器之间数据格式校验的细微差异.
    Js跳转代码代替RedirectToAction是否违背MVC
    情 人 节 快 乐
    UCenter 1.5.0 整合 Bug
    ping [主机名] 4
    关于VS2008调试时端口号不一致的问题
  • 原文地址:https://www.cnblogs.com/lunar-ubuntu/p/14488369.html
Copyright © 2011-2022 走看看