• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

【译】关于Rust模块的清晰解释

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

原文链接: http://www.sheshbabu.com/posts/rust-module-system/
原文标题: Clear explanation of Rust’s module system
公众号: Rust碎碎念
翻译: Praying

Rust的模块(module)系统相当令人困惑,这也给很多初学者带来了挫败感。

在本文中,我将会通过实际的例子来解释模块系统以便于让你清晰地理解它是怎样工作的并且能够快速在自己的项目中应用。

由于Rust的模块系统比较独特,我希望读者以开放性思维来进行阅读,并且尽量不要将其与其他语言中的模块的工作方式进行比较。

让我们使用下面的文件结构来模拟一个真实世界中的项目:

my_project
├── Cargo.toml
└─┬ src
  ├── main.rs
  ├── config.rs
  ├─┬ routes
  │ ├── health_route.rs
  │ └── user_route.rs
  └─┬ models
    └── user_model.rs

下面是一些使用我们的模块的不同方式:

下面的3个例子应该足以解释Rust的模块系统是如何工作的。

示例1

让我们从第一个例子开始 —— 在main.rs中导入config.rs

// main.rs
fn main() {
  println!("main");
}
// config.rs
fn print_config() {
  println!("config");
}

很多人常犯的第一个错误是因为我们有像config.rshealth_route.rs这样的文件,所以我们就认为这些文件就是模块(module)且可以在其他的文件中将其导入。

下面是从我们的视角(文件系统树(file system tree))看到的内容和从编译器的角度(模块树(module tree))看到的内容:

令人惊奇,编译器只看到了crate模块,也就是我们的main.rs文件。这是因为我们需要显式地在Rust中构建模块树——在文件系统树和模块树之间不存在隐式的转换。

我们需要显式地在Rust中构建模块树——在文件系统树和模块树之间不存在隐式的转换。

想要把一个文件添加到模块树中,我们需要使用mod关键字来将这个文件声明为一个子模块(submodule)。另一件使人们感到困惑的事情是你会认为在相同的文件里把一个文件声明为模块(译者注:比如使用mod关键字把config.rs声明为子模块,你可能认为需要在config.rs里来写声明)。但是我们需要在一个不同文件里进行声明!因为我们在这个模块树里只有main.rs这个文件,所以要在main.rs里将config.rs声明为一个子模块。

mod 关键字声明一个子模块

mod关键字语法如下:

mod my_module;

这里,编译器在相同的目录下查找my_module.rs或者my_module/mod.rs

my_project
├── Cargo.toml
└─┬ src
  ├── main.rs
  └── my_module.rs

或者

my_project
├── Cargo.toml
└─┬ src
  ├── main.rs
  └─┬ my_module
    └── mod.rs

因为main.rsconfig.rs在相同的目录下,让我们按照下面的代码声明config模块

// main.rs
mod config;

fn main() {
+ config::print_config();
  println!("main");
}
// config.rs
fn print_config() {
  println!("config");
}

这里,我们通过::语法使用print_config函数。 下面是模块树的样子:

我们已经成功地声明了config模块!但是这还不能调用config.rs里的print_config函数。几乎Rust里面的一切默认都是私有(private)的,我们需要使用pub关键字来让这个函数成为公开(public)的:

pub关键字使事物公开

// main.rs
mod config;

fn main() {
  config::print_config();
  println!("main");
}
// config.rs
fn print_config() {
pub fn print_config() {
  println!("config");
}

现在,这样可以正常工作了。我们已经成功的调用了定义在另一个文件里的函数!

示例2

让我们尝试在main.rs中调用定义在routes/health_route.rs里的print_health_route函数。

// main.rs
mod config;

fn main() {
  config::print_config();
  println!("main");
}
// routes/health_route.rs
fn print_health_route() {
  println!("health_route");
}

正如我们之前所讨论的,我们只能对相同目录下的my_module.rs或者my_module/mod.rs使用mod关键字。 所以为了能够在main.rs中调用routes/health_route.rs里定义的函数,我们需要做下面的事情:

  • 创建一个名为routes/mod.rs的文件并且在main.rs中声明routes子模块

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
MATLAB新手教程发布时间:2022-07-18
下一篇:
【Matlab】如何使用Simulink进行电池建模和SOC预估发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap