Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to have multiple files with one module?

Tags:

module

rust

I don't understand why we have only one file per module.

// main.rs

mod dog; // Find dog in dog.rs or dog/mod.rs
fn main() {
    dog::sonic_bark();
}

When dog grows larger and has lots of functions, it's not good to have all of them in one file.

How I can separate them without using

dog::leg::walk();
dog::head::nose::smell();
dog::tail::iron_tail();
dog::mouth::sonic_bark();

I want to just use dog::sonic_bark();

like image 884
Masked Man Avatar asked Feb 14 '17 07:02

Masked Man


People also ask

How to create multiple files on Linux system?

When you have decided to create multiple files on your Linux system, all you need is the touch command that you will definitely find on your system, and the last thing you should know is how you want to name them. After that, you just need to follow the below syntax to create multiple files at once by just invoking the single command.

Can a module expose two classes and two functions?

Responded with example, tested in interactive terminal just now. In the example, I do not want the namespaces created by the names of the python files to be in the module, because it's cluttered. The module should expose two classes and two functions, not two classes, two functions, and two submodules each containing a class and a function.

How is a multi-module project built?

A multi-module project is built from an aggregator POM that manages a group of submodules. In most cases, the aggregator is located in the project's root directory and must have packaging of type pom.

What is multi module project in Maven?

Maven's Multi-Module Project A multi-module project is built from an aggregator POM that manages a group of submodules. In most cases, the aggregator is located in the project's root directory and must have packaging of type pom.


2 Answers

You cannot.

You can have more modules than files (the typical examples being mod tests nested in the file), but not the reverse.


However, this does not matter because you can use encapsulation + re-export.

The default when declaring a submodule with mod xxx; is that xxx is private: no user of the current module will know that it depends on xxx.

Combine this with selecting re-exporting symbols:

pub use self::leg::walk;
pub use self::head::nose::smell;
pub use self::tail::iron_tail;
pub use self::mouth::sonic_bark;

And you can call those directly: dog::walk(), dog::smell(), ...

Therefore, private imports and public re-exports help you have a hidden internal hierarchy while exposing a flat public interface.


Complete example:

mod dog {
    pub use self::head::nose::smell;
    pub use self::leg::walk;
    pub use self::mouth::sonic_bark;
    pub use self::tail::iron_tail;

    mod leg {
        pub fn walk() {}
    }

    mod head {
        pub mod nose {
            pub fn smell() {}
        }
    }

    mod tail {
        pub fn iron_tail() {}
    }

    mod mouth {
        pub fn sonic_bark() {}
    }
}

fn main() {
    dog::sonic_bark();
}
like image 126
Matthieu M. Avatar answered Sep 23 '22 01:09

Matthieu M.


It is possible, but you should absolutely not do this because it's unidiomatic, will probably break various tools and IDEs, and is just generally confusing. Please don't read this except for educational purposes.


The trick is to use include! to directly import source code.

Filesystem

do-not-do-this
├── Cargo.toml
├── src
│   ├── dog-head.rs
│   ├── dog-tail.rs
│   ├── dog.rs
│   └── main.rs

src/main.rs

mod dog;

fn main() {
    dog::bark();
    dog::wag();
}

src/dog.rs

include!("dog-head.rs");
include!("dog-tail.rs");

src/dog-head.rs

pub fn bark() {
    eprintln!("Woof");
}

src/dog-tail.rs

pub fn wag() {
    eprintln!("Swish");
}
like image 32
Shepmaster Avatar answered Sep 22 '22 01:09

Shepmaster