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

释放双眼,带上耳机,听听看~!

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

实用知识

代码组织与模块化

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

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

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

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


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

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

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

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

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

我们来看看完整的代码:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1fn greet() -> String {
2    // return getString();
3    return greetings::hello();
4}
5
6mod greetings {
7    // ⭐️ By default, everything inside a module is private
8    pub fn hello() -> String {
9        // ⭐️ So function has to be public to access from outside
10        return String::from("Hello, world!");
11    }
12    //private funtions
13    fn getString() -> String {
14        return String::from("Hello, world!");
15    }
16}
17
18#[cfg(test)] // Only compiles when running tests
19mod tests;
20
21

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

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


1
2
3
4
5
6
7
8
1mod phrases {
2    pub mod greetings {
3        pub fn hello() -> String {
4            return String::from("Hello, world!");
5        }
6    }
7}
8

lib.rs完整代码如下 :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
1fn greet() -> String {
2    // return getString();
3    //return greetings::hello();
4    return phrases::greetings::hello();
5}
6
7mod greetings {
8    // ⭐️ By default, everything inside a module is private
9    pub fn hello() -> String {
10        // ⭐️ So function has to be public to access from outside
11        return String::from("Hello, world!");
12    }
13    //private funtions
14    fn getString() -> String {
15        return String::from("Hello, world!");
16    }
17}
18mod phrases {
19    pub mod greetings {
20        pub fn hello() -> String {
21            return String::from("Hello, world!");
22        }
23    }
24}
25#[cfg(test)] // Only compiles when running tests
26mod tests;
27
28

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

得到的结果是:


1
2
3
4
5
6
1running 2 tests
2test tests::it_works ... ok
3test tests::test_greet ... ok
4
5test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
6

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


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

lib.rs中的代码如下 :


1
2
3
4
5
6
7
8
9
1mod greetter; // Import greetter module
2fn greet() -> String {
3    return greetter::hello();
4}
5
6#[cfg(test)] // Only compiles when running tests
7mod tests;
8
9

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

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


1
2
3
4
5
6
7
8
9
10
1// ↳ phrasing.rs
2pub mod greetings {
3    // ⭐️ The module has to be public to access from outside
4    pub fn hello() -> String {
5        // The function has to be public to access from outside{
6        return String::from("Hello, world!");
7    }
8}
9
10

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


1
2
3
4
5
6
7
8
9
10
11
12
1// mod greetter; // Import greetings module
2mod phrasing;
3
4fn greet() -> String {
5    return phrasing::greetings::hello();
6}
7
8
9#[cfg(test)] // Only compiles when running tests
10mod tests;
11
12

以上代码,也测试通过。

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

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

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


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

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

我们在怎么引用呢?

看我们在lib.rs的代码:


1
2
3
4
5
6
7
8
9
10
11
1mod calling;// Import calling module
2
3fn greet() -> String {
4    return calling::hello();
5}
6
7
8#[cfg(test)] // Only compiles when running tests
9mod tests;
10
11

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

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


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

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


1
2
3
4
5
6
7
8
9
10
11
12
1mod calling;// Import calling module
2
3fn greet() -> String {
4
5    return calling::greetings::hello();
6}
7
8
9#[cfg(test)] // Only compiles when running tests
10mod tests;
11
12

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


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

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


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

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


1
2
3
4
5
6
7
8
9
10
11
12
1// mod greetter; // Import greetings module
2mod calling; // Import calling module
3
4fn greet() -> String {
5    return calling::hello();
6}
7
8
9#[cfg(test)] // Only compiles when running tests
10mod tests;
11
12

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

可以的。

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


1
2
1pub mod other;
2

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

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


1
2
3
4
5
6
7
8
9
10
11
1mod calling; // Import calling module
2
3fn greet() -> String {
4    return calling::other::hello();//直接可以访问other模块的方法hello()
5}
6
7
8#[cfg(test)] // Only compiles when running tests
9mod tests;
10
11

以上,希望对你有用。


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

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

给TA打赏
共{{data.count}}人
人已打赏
安全技术

C/C++内存泄漏及检测

2022-1-11 12:36:11

安全经验

java高并发(十)线程不安全类与写法

2021-11-28 16:36:11

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索