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


    [易学易懂系列|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

  • 相关阅读:
    MySQL——SELECT
    启动 MySQL
    Ethernet and ARP 及Wireshark实验
    ICMP 协议及Wireshark实验
    Wireshark实验——IP 协议
    关键路径
    用树结构存储的图博客(笑)
    拓扑排序
    云计算部署的未来趋势将从自动化转向为自主化
    苹果拥抱 Rust,正在将 C 代码移植到 Rust
  • 原文地址:https://www.cnblogs.com/gyc567/p/12003450.html
Copyright © 2020-2023  润新知