[易学易懂系列|rustlang语言|零基础|快速入门|(16)|代码组织与模块化]

实用知识

代码组织与模块化

我们知道,在现代软件开发的过程中,代码组织和模块化是应对复杂性的一种方式。

今天我们来看看Rust是怎么做代码组织和模块化的。

Rust用mod 关键字来定义模块。

我们还是拿上一篇文章中的代码来作例子,我们在原来的代码lib.rs加入新的mod:

mod greetings {
// ⭐️ By default, everything inside a module is private
pub fn hello() -> String {
// ⭐️ So function has to be public to access from outside
return String::from("Hello, world!");
}
}

其中:pub fn hello(),是定义一个公共的方法hello。

Rust用关键词pub关键词来定义公共的方法,代表这个方法可以在这个模块外访问。

一般情况下,fn默认是私有的,也就是说它只能在本模块或本模块的子模块内访问。

这个跟一般的开发语言,比如java的访问控制习惯是一样的。好理解。

我们来看看完整的代码:

fn greet() -> String {
// return getString();
return greetings::hello();
} mod greetings {
// ⭐️ By default, everything inside a module is private
pub fn hello() -> String {
// ⭐️ So function has to be public to access from outside
return String::from("Hello, world!");
}
//private funtions
fn getString() -> String {
return String::from("Hello, world!");
}
} #[cfg(test)] // Only compiles when running tests
mod tests;

我们用cargo test运行测试代码,得到的结果是pass的。

模块也是可以嵌套的,我们在lib.rs加入如下代码 :

mod phrases {
pub mod greetings {
pub fn hello() -> String {
return String::from("Hello, world!");
}
}
}

lib.rs完整代码如下 :

fn greet() -> String {
// return getString();
//return greetings::hello();
return phrases::greetings::hello();
} mod greetings {
// ⭐️ By default, everything inside a module is private
pub fn hello() -> String {
// ⭐️ So function has to be public to access from outside
return String::from("Hello, world!");
}
//private funtions
fn getString() -> String {
return String::from("Hello, world!");
}
}
mod phrases {
pub mod greetings {
pub fn hello() -> String {
return String::from("Hello, world!");
}
}
}
#[cfg(test)] // Only compiles when running tests
mod tests;

同样我们用命令运行:cargo test

得到的结果是:

running 2 tests
test tests::it_works ... ok
test tests::test_greet ... ok test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

我们再把方法移到另一个文件greetter.rs中,如下:

// ↳ greetter.rs
// ⭐️ No need to wrap the code with a mod declaration. The file itself acts as a module.} pub fn hello() -> String {
// The function has to be public to access from outside{
return String::from("Hello, world!");
}

lib.rs中的代码如下 :

mod greetter; // Import greetter module
fn greet() -> String {
return greetter::hello();
} #[cfg(test)] // Only compiles when running tests
mod tests;

我们再运行测试,结果应该是全通过。

现在我们再来看看不同文件中的嵌套模块的代码,我们新建一个文件phrasing.rs:

// ↳ phrasing.rs
pub mod greetings {
// ⭐️ The module has to be public to access from outside
pub fn hello() -> String {
// The function has to be public to access from outside{
return String::from("Hello, world!");
}
}

然后我们在lib.rs中文件中调用相关方法,如下 :

// mod greetter; // Import greetings module
mod phrasing; fn greet() -> String {
return phrasing::greetings::hello();
} #[cfg(test)] // Only compiles when running tests
mod tests;

以上代码,也测试通过。

现在我们来看看,另一种情况:不同文件,不同目录。

我们在src目录中新建一个目录:calling。

在目录calling中,我们新建一个mob.rs,我们在这个mob.rs中写入如下代码:

pub fn hello() -> String {
// ⭐️ The function has to be public to access from outside
return String::from("Hello, world!");
}

在Rust中,mob.rs指向当前根目录,代表当前目录的模块,这里是:calling目录。

我们在怎么引用呢?

看我们在lib.rs的代码:

mod calling;// Import calling module

fn greet() -> String {
return calling::hello();
} #[cfg(test)] // Only compiles when running tests
mod tests;

同样,我们测试是通过的。

我们再看看在mod.rs文件定义一个mod,这也代表一个嵌套mod模块:

//calling/mod.rs
pub mod greetings {
// ⭐️ The module has to be public to access from outside
pub fn hello() -> String {
return String::from("Hello, world!");
}
}

我们在lib.rs中调用,则用如下代码:

mod calling;// Import calling module

fn greet() -> String {

    return calling::greetings::hello();
} #[cfg(test)] // Only compiles when running tests
mod tests;

我们再来看看另一种情况,我们在calling目录下新建一个文件other.rs,代码:

//calling/other.rs
pub fn hello() -> String {
// The function has to be public to access from outside{
return String::from("Hello, world!");
}

这时我们在calling/mob.rs文件中的代码如下:

mod other;// Import other module
pub fn hello() -> String {
// ⭐️ The function has to be public to access from outside
return other::hello();
}

我们在lib.rs的代码如下 :

// mod greetter; // Import greetings module
mod calling; // Import calling module fn greet() -> String {
return calling::hello();
} #[cfg(test)] // Only compiles when running tests
mod tests;

我们发现这种方式好像复杂了一点,能否直接从lib.rs直接调用other.rs的代码呢?

可以的。

我们只要把文件:calling/mob.rs的代码改为如下 代码 :

pub mod other;

这段代码的含义是:把other.rs这个模块导入为公共模块。

这时,我们的lib.rs代码如下 :

mod calling; // Import calling module

fn greet() -> String {
return calling::other::hello();//直接可以访问other模块的方法hello()
} #[cfg(test)] // Only compiles when running tests
mod tests;

以上,希望对你有用。

如果遇到什么问题,欢迎加入:rust新手群,在这里我可以提供一些简单的帮助,加微信:360369487,注明:博客园+rust

参考:https://learning-rust.github.io/docs/d3.modules.html

[易学易懂系列|rustlang语言|零基础|快速入门|(16)|代码组织与模块化]的更多相关文章

  1. [易学易懂系列|rustlang语言|零基础|快速入门|(28)|实战5:实现BTC价格转换工具]

    [易学易懂系列|rustlang语言|零基础|快速入门|(28)|实战5:实现BTC价格转换工具] 项目实战 实战5:实现BTC价格转换工具 今天我们来开发一个简单的BTC实时价格转换工具. 我们首先 ...

  2. [易学易懂系列|rustlang语言|零基础|快速入门|(27)|实战4:从零实现BTC区块链]

    [易学易懂系列|rustlang语言|零基础|快速入门|(27)|实战4:从零实现BTC区块链] 项目实战 实战4:从零实现BTC区块链 我们今天来开发我们的BTC区块链系统. 简单来说,从数据结构的 ...

  3. [易学易懂系列|rustlang语言|零基础|快速入门|(26)|实战3:Http服务器(多线程版本)]

    [易学易懂系列|rustlang语言|零基础|快速入门|(26)|实战3:Http服务器(多线程版本)] 项目实战 实战3:Http服务器 我们今天来进一步开发我们的Http服务器,用多线程实现. 我 ...

  4. [易学易懂系列|rustlang语言|零基础|快速入门|(25)|实战2:命令行工具minigrep(2)]

    [易学易懂系列|rustlang语言|零基础|快速入门|(25)|实战2:命令行工具minigrep(2)] 项目实战 实战2:命令行工具minigrep 我们继续开发我们的minigrep. 我们现 ...

  5. [易学易懂系列|rustlang语言|零基础|快速入门|(24)|实战2:命令行工具minigrep(1)]

    [易学易懂系列|rustlang语言|零基础|快速入门|(24)|实战2:命令行工具minigrep(1)] 项目实战 实战2:命令行工具minigrep 有了昨天的基础,我们今天来开始另一个稍微有点 ...

  6. [易学易懂系列|rustlang语言|零基础|快速入门|(23)|实战1:猜数字游戏]

    [易学易懂系列|rustlang语言|零基础|快速入门|(23)|实战1:猜数字游戏] 项目实战 实战1:猜数字游戏 我们今天来来开始简单的项目实战. 第一个简单项目是猜数字游戏. 简单来说,系统给了 ...

  7. [易学易懂系列|rustlang语言|零基础|快速入门|(5)|生命周期Lifetime]

    [易学易懂系列|rustlang语言|零基础|快速入门|(5)] Lifetimes 我们继续谈谈生命周期(lifttime),我们还是拿代码来说话: fn main() { let mut a = ...

  8. [易学易懂系列|rustlang语言|零基础|快速入门|(22)|宏Macro]

    [易学易懂系列|rustlang语言|零基础|快速入门|(22)|宏Macro] 实用知识 宏Macro 我们今天来讲讲Rust中强大的宏Macro. Rust的宏macro是实现元编程的强大工具. ...

  9. [易学易懂系列|rustlang语言|零基础|快速入门|(21)|智能指针]

    [易学易懂系列|rustlang语言|零基础|快速入门|(21)|智能指针] 实用知识 智能指针 我们今天来讲讲Rust中的智能指针. 什么是指针? 在Rust,指针(普通指针),就是保存内存地址的值 ...

  10. [易学易懂系列|rustlang语言|零基础|快速入门|(20)|错误处理]

    [易学易懂系列|rustlang语言|零基础|快速入门|(20)|错误处理] 实用知识 错误处理 我们今天来讲讲Rust中的错误处理. 很多语言都有自己的错误处理方式,比如,java是异常处理机制. ...

随机推荐

  1. Ajax操作的四个步骤

    Ajax操作的四个步骤: 创建Ajax对象 连接服务器 发送请求 接收返回信息 <!DOCTYPE html> <html> <head lang="en&qu ...

  2. react 添加代理 proxy

    react package.json中proxy的配置如下 "proxy": { "/api/rjwl": { "target": &quo ...

  3. C# 重写WndProc

    重写WndProc方法来处理 Windows 消息 处理 Windows 消息. 在开发winForm时,常常要处理Windows消息,可以重写WndProc来实现.常见代码如下: using Sys ...

  4. 在 sys.servers 中找不到服务器 '10.0.2.13'。请验证指定的服务器名称是否正确。

    工作中,因为需要,搭建同事的程序模块,附加了从同事那里拷过来的该程序使用的库.(C#.C/S..Net Framework4.0 .WCF.Win10.SQL Server 2014.VS2015) ...

  5. .Net Core Web应用加载读取Json配置文件

    ⒈添加Json配置文件并将“复制到输出目录”属性设置为“始终复制” { "Logging": { "LogLevel": { "Default&quo ...

  6. Luogu P2569 [SCOI2010] 股票交易

    此题链接到dp常见优化方法 开始的时候被纪念品误导,以为是多支股票,后来发现事情不妙: 这道题知道的是某一只股票的走势: \(Solution\): \(70pts\): 设\(f[i][j]\)表示 ...

  7. c++学习之对象和类——构造函数和析构函数

    再认真理一遍~ 0.类 这里先来定义一个类,便于后面的理解.参考C++ Primer Plus class Stock { private: std::string company; long sha ...

  8. spark教程(11)-sparkSQL 数据抽象

    数据抽象 sparkSQL 的数据抽象是 DataFrame,df 相当于表格,它的每一行是一条信息,形成了一个 Row Row 它是 sparkSQL 的一个抽象,用于表示一行数据,从表现形式上看, ...

  9. Codeforces 1201E2. Knightmare (hard)

    传送门 看到棋盘先黑白染色冷静一下 然后分析发现,如果初始时两只马在同色的格子,那么一定是后手吃先手 反之一定是先手吃后手 所以分类讨论一下,如果初始在同色的格子,并且后手到达终点的步数更少,那么后手 ...

  10. Erasing Substrings CodeForces - 938F (字符串dp)

    大意: 给定字符串$s$, 长度为$n$, 取$k=\lfloor log2(n)\rfloor$, 第$i$次操作删除一个长度为$2^{i-1}$的子串, 求一种方案使得, $k$次操作后$s$的字 ...