user1663023
user1663023

Reputation:

rust mod statement's inconsistency

Following the example in separating modules into different files from the following link: https://doc.rust-lang.org/book/ch07-02-modules-and-use-to-control-scope-and-privacy.html#separating-modules-into-different-files

I have created the following files under src directory:

├── main.rs
├── sound
│   └── instrument.rs
└── sound.rs

In src/main.rs:

mod sound;

fn main() {
  // Absolute path
  crate::sound::instrument::clarinet();

  // Relative path
  sound::instrument::clarinet();
}

In src/sound.rs:

pub mod instrument;

And in src/sound/instrument.rs:

pub fn clarinet() {
  println!("clarinet");
}

The example compiles and works as expected. Now my questions is: why in main.rs, it can "mod" the sound.rs from the same directory, while in sound.rs, it has to "mod" the instrument.rs from a sub-directory

Upvotes: 0

Views: 312

Answers (1)

Benjamin Lindley
Benjamin Lindley

Reputation: 103693

In a standard Rust bin project, src/main.rs is given a special position as the crate root. Other source files within src/ are modules at the top level of the crate. Modules with multiple files can take one of two forms. The old way was like this:

├── main.rs
└── mod_name
    └── mod.rs
    └── submodule.rs
└── some_other_mod.rs

mod.rs was required (with that exact name), and would serve as the top level of the module. In this case you can see, I'm sure, that it wouldn't make sense for src/mod_name/mod.rs to refer to some_other_mod directly without prefixing it with super:: or crate::.

The new method, which you are using, allows you to forgo mod.rs and just have mod_name.rs in the parent mod's directory, which serves the same purpose as mod.rs. This is convenient for when you start developing a library as a single file, and then when you later decide to add more files, you aren't required to rename and move the top level file.

In your case, instrument.rs needs to be in the sound/ directory in order to be considered part of the sound module. If you placed it directly in src/, it would be considered a top level module in the crate.

Upvotes: 3

Related Questions