I want to split a Rust program into multiple files, but the use of mod
doesn't see to allow me to reference files in the same directory from files other than main.rs
.
For example, if I have main.rs
, game.rs
, and matrix.rs
in the same folder, I can reference structs/functions from game.rs
or matrix.rs
in main.rs
with a mod game;
or mod matrix;
. I can't, however, reference matrix.rs
from game.rs
with a statement like mod matrix
.
I've looked at several resources and all of them only have modules structures like trees that don't reference each other. Is it possible to use structs/functions from files in each other in Rust, or is that against the rules? If so, why doesn't Rust let you do that?
mod
is module declaration. This directive declares a module and all of its contents. It just so happens that these contents may be located in another file. So this:
mod game;
mod matrix;
is roughly equivalent to this:
mod game {
// game.rs contents
}
mod matrix {
// matrix.rs contents
}
Naturally, since mod
is a declaration of a module, you can't do it multiple times for the same module. That is, you can try and write something like
mod game {
mod matrix;
...
}
mod matrix;
but, as you can see, matrix
and game::matrix
are different modules, and naturally rustc requires different paths to their respective files, if they are external.
use
, however, is import declaration. use
declarations pull names from other modules for use in the current module. You can use
any module and any public items from it any number of times from anywhere this module is accessible.
So, in order to reference matrix
from game
you need to use
it:
// game.rs
use matrix;
Naturally, in order for this to work matrix
should be declared with mod
in the crate root.
As a side note, I personally think that the simplest way to understand Rust module system is to first forget that modules can be put in different files at all. That is, think as if a crate can only be defined in a single file. In Rust mod
directives can have bodies and can nest, so nested mod
s actually define the module system of a crate:
mod foo {
mod bax {
...
}
mod baz {
...
}
}
mod bar {
mod qux {
mod zux {
...
}
}
}
If you only have a single file, you can easily see how mod
and use
directives would work, and relationship between modules should become clear.
And now you only need to add to the picture the fact that if a module is declared without a body, like in mod name;
, its content is loaded either from name.rs
or name/mod.rs
, whatever is available. However, the full picture does not change in the slightest - these still are nested modules which can always be represented as a single source file with nested mod
directives. In fact, cargo rustc -Z unstable-options --pretty=normal
will print your crate in this form, after all modules in external source files are assembled into a single document. I suggest running this command on some crates with complex module structure to see how it looks in practice.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With