31

I'm struggling to wrap my head around these,

  • use declaration

    A use declaration creates one or more local name bindings synonymous with some other path. Usually, a use declaration is used to shorten the path required to refer to a module item. These declarations may appear in modules and blocks, usually at the top.

And,

  • mod item

    A module item is a module, surrounded in braces, named, and prefixed with the keyword mod. A module item introduces a new, named module into the tree of modules making up a crate. Modules can nest arbitrarily.

Basically, when I go to layout my module, I believe I know how I want it layed out but I get confused about how these two things should be layered and what they do. I would think only one of the two would include code?

Yilmaz
  • 35,338
  • 10
  • 157
  • 202
Evan Carroll
  • 78,363
  • 46
  • 261
  • 468
  • 13
    In short: `mod` means "here's the new module (from file or in curly brackets), store it for future use", `use` means "there's already created module, pull it from this path and let me use it here". – Cerberus Apr 02 '21 at 12:31

3 Answers3

30

Consider you have a module my_mod with a pub function my_func. You can't use this function in your crate (or outside your crate) until you include your module using mod my_mod statement.

After you include your module, you can use your function like that:

mod my_mod;

...
my_mod::my_func(...)
...

You can't use my_mod::my_func statement if you don't include your module somewhere in your crate.

Sometimes it is better to import frequently used definitions:

mod my_mod;
use my_mod::my_func;

Now you if you want to use you function you can just write:

my_func(...);

You can also re-export definitions of sub-modules (or even other crates!) using pub use statement.

If you working with other crates imported through Cargo.toml (by listing them as dependencies), you may import definitions from these crates using only use statement.

Suraaj K S
  • 600
  • 3
  • 21
Dmitry
  • 1,426
  • 5
  • 11
15

The language documentation tries but misses a few important concepts implied by mod and I have had to do test to figure this out. To try an save others the time I offer the following conclusions...

  1. The module system hierarchy forms a source tree similar to a file system directory wherein mod selects an immediate child modules relative to its host module. Importantly, these module files referenced by mod are required to be held inside a sub-directory that is (1) within the same directory as the host module file and (2) that sub-directory must have the same name as the host module file. That means modules cannot import sibling, parents, grandchildren, or cousin modules. *The apparent exception to this hierarchical containment pattern and perhaps the source of much confusion are the root modules (main.rs, lib.rs). These particular module files do occur within src/ alongside their sub-modules; however, they are special. Specifically, these crate root module files (main.rs, lib.rs, bin/other_root.rs) are actually treated as parent modules to the src/ directory itself. (As such, at compile time they treated as being named either /src.rs with an associated sub-directory /src/ or (better yet) as the root module, src/mod.rs, within the src/ directory itself).
  2. The crate root modules (and also Cargo.toml) constructs a source tree by selecting modules in the root of the src/ directory. These modules may then include a selection from their associated module sub-directories, then those modules from their associated module sub-directories, and so on. The resultant tree of included module files becomes the source code available in the crate. Importantly, crate roots modules (lib.rs, main.rs, bin/other_crate_root.rs) may actually select different initial modules from the `/src' directory and thereby evolve a different tree of modules.
  3. Finally, once a module does exist within the source tree of a crate it may be referred to by its path (depending on visibility constraints). In particular, the use statement may now be used to abbreviate the path to the module and/or its externally visible contents.
George
  • 2,451
  • 27
  • 37
  • Are you sure about the "only being able to import immediate child modules" part? It seems possible using `crate::` or `super::` (what I'd call "absolute" and "relative" imports respectively). – Gustavo Bezerra Mar 31 '22 at 04:30
  • `use` is different from `mod`. `use` provides for the abbreviation references to contents of the source tree. `mod` establishes the source tree. – George Mar 31 '22 at 08:37
12

mod keyword is like import statement. You bring the content from outside file.

 // another_file is the name of the file, another_file.rs
 // file name is default module
 mod another_file

Now you brought the content. use is used to create a path top-level so you could use a function or struct in multiple parts. Let's say you have to reach a struct deep inside the module:

// mod could be in the same file: my_game::education::learning_rust::Person;
// in main.rs you dont need to use `use crate::another_file`. you would use `use crate` if you were in other module
use another_file::my_game::education::learning_rust::Person;

then inside main

fn main(){
    let person=Person::new()
    person.display_info();
    }

If I did not use use keyword, everwhere I needed Person struct I would write this:

let person=another_file::my_game::education::learning_rust::Person::new()
  • Also if you want to access standard library features, you use use

    use std::net;
    use std::io::prelude::*;
    
Yilmaz
  • 35,338
  • 10
  • 157
  • 202
  • 1
    What's the relationship between the `mod` statement in your example and the `mod` declaration for an actual module...? So if I have a file named `a.rs`, then inside `a.rs` I define a module like so `pub mod a`. I want to use the functions from `a.rs` in main, so do I _still_ need a _second_ `mod a` statement in main? – Raleigh L. Jul 12 '23 at 08:01