this post was submitted on 08 Nov 2023
13 points (88.2% liked)
Rust
6028 readers
1 users here now
Welcome to the Rust community! This is a place to discuss about the Rust programming language.
Wormhole
Credits
- The icon is a modified version of the official rust logo (changing the colors to a gradient and black background)
founded 1 year ago
MODERATORS
you are viewing a single comment's thread
view the rest of the comments
view the rest of the comments
If you want your module to contain submodules, it needs to go into a folder. That folder needs to be named like the module.
It's explained pretty well in the book, imho: https://doc.rust-lang.org/stable/book/ch07-02-defining-modules-to-control-scope-and-privacy.html
So, for your example, the file structure could for instance be
src/main.rs
src/separate_file1.rs
src/separate_file1/separate_file2.rs
An alternative layout that I think is more common would be
src/main.rs
src/separate_file1/mod.rs
src/separate_file1/separate_file2.rs
Or, if you think separate_file2 could contain submodules at some point, maybe
src/main.rs
src/separate_file1/mod.rs
src/separate_file1/separate_file2/mod.rs
Yeah, it's tricky that the file for a module is in a subfolder under the file that declared it, unless the file that declared it is named
main.rs
,lib.rs
, ormod.rs
in which cases the module file is in the same folder, not in a subfolder. There is logic to it, but you have to connect multiple rules to get there.We see in the examples above that a module named
whatever
can be inwhatever.rs
or inwhatever/mod.rs
and you get the same result.mod.rs
is a special name with a special lookup rule.whatever/mod.rs whatever/submodule_of_whatever.rs
works exactly the same aswhatever.rs whatever/submodule_of_whatever.rs
. We usemod.rs
so we don't have to have both a folder and an.rs
file with the same name. But that leads to the special exception where submodules declared inmod.rs
are defined by files in the same folder asmod.rs
.main.rs
is like themod.rs
of the entire crate.main.rs
has a special rule where it's in the same folder as its submodules, instead of the normal rule where submodules are in a subfolder.lib.rs
fellows the same special rule asmain.rs
. (You usemain.rs
to define an executable,lib.rs
to define a library.)It is not that tricky if you shift your perspective. Rather than thinking about files importing files (like you would in other languages), think about the crate as a tree of modules. Then the rules are simple.
main.rs
andlib.rs
are the entry points to the crate and define the root module. Other modules are nested under this and may exist in a file that matches the modules path in the tree. So a module atcrate::foo::bar::baz
can live in eitherfoo/bar/baz.rs
orfoo/bar/baz/mod.rs
. Or be defined as a inline module in the parent module (which may also be defined inline in its parent).This also means if you know the file path you know where it will exist in the tree,
a/b/c/d.rs
will be at the crate patha::b::c::d
.Yes, I like your explanations and I agree that's the way to think about it. But either way you have some special exceptions because
main.rs
maps tocrate
instead of tocrate::main
, anda/mod.rs
maps tocrate::a
instead of tocrate::a::mod
. I know that's the same thing you said, but I think it's worth emphasizing that the very first file you work with is one of the exceptions which makes it harder to see the general rule. It works just the way it should; but I sympathize with anyone getting started who hasn't internalized the special and general rules yet.