Git repo: https://github.com/caveofprogramming/rust/
Defining Modules Within a File
To define a module in main.rs
, we can use the mod
keyword.
By default everything within a module is private to that module. To enable external code to access variables, types, functions or sub-modules within a module, we have to declare them with pub
.
If we declare an enum
within a module, we can use the enum
and all its constants as long as it’s declared pub
.
With a struct
, any fields you want to be accessible outside the module must individually be declare pub
too.
We can import the actual function so that it can be used without any prefix, with a use
statement, but it’s recommended to always prefix functions with the name of their immediate module, for disambiguation and clarity.
We can also use a glob to include all functions in a module, but again, not recommended.
We can create sub-modules within modules. Again they can’t be accessed externally without being declared with the pub
keyword.
If you need to access the parent module of a module (for example, to then access parallel modules), you can use the super
keyword.
You can use “re-exporting” to flatten the structure of modules, in regard to the way they are accessed.
Let’s make it possible to access the menageries::speak()
function directly from the animals
module.
Here I’ve also used the as
keyword to give the speak
function a different name.
Modules in Other Files
If we create a file next to main.rs
called fruits.rs
, we can then declare it to be a fruits
module in main.rs
, and can then use public entities from it.
fruits.rs:
main.rs:
We can also create modules using directories.
Here I've renamed fruits.rs
to mod.rs
and put it in a folder called fruits
.
The code remains the same.
mod.rs:
main.rs:
When Rust sees mod fruits;
in main.rs
, it will look for either a file called fruits.rs
or else a directory called fruits
with a mod.rs
within it.
We can load other module files in mod.rs
instead, or as well.
mod.rs:
apple.rs:
main.rs:
Here I’ve placed a use
statement in main.rs
so I can refer to apple
directly, without going via fruits
.
Files:
Creating Programs Consisting of an Executable and a Library
We can create programs in which most of the code, or some of the code, is in a reusable library, and main
just uses code from that library.
To do this we need a lib.rs
.
main.rs
and lib.rs
are the two files the Rust compiler looks for by default, without being told to load them.
cities.rs:
lib.rs:
main.rs:
Note that the modules loaded in lib.rs
have to be accessed via the package name set when using cargo new
. In this case I originally created this package with cargo new locations
.
Now as well as the locations
executable in the target/debug
directory, we also have liblocations.rlib
, a reusable library.