Rust use vs mod?
Asked Answered
P

4

37

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?

Piazza answered 2/4, 2021 at 7:37 Comment(1)
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".Gravy
W
35

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, if you want to use your 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.

Willywilly answered 2/4, 2021 at 9:0 Comment(3)
Thanks @Dmitry, so as I understand, the keyword "use" is like the use namespace of other languages like c# or c++?Qr
Why do you need mod if there is use?Shira
@Shira you cant use the module in another .rs file if the module is not mod-edTheory
R
18

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.
Richelle answered 8/12, 2021 at 4:14 Comment(2)
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).Alwitt
use is different from mod. use provides for the abbreviation references to contents of the source tree. mod establishes the source tree.Richelle
P
16

mod keyword is like import statement. You bring the content from outside file to be accessible. Rust needs to know about the existence of the module. (For external dependencies specified in Cargo.toml, Rust and Cargo allows you to use their items directly without manually declaring each crate.)

 // another_file is the name of the file, another_file.rs
 // file name is default module. every file create a 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;

With use declaration, we are bringing the Person into the scope.

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()

By reducing the need to write full paths repeatedly, use improves the readability and maintainability of your code.

  • Also if you want to access standard library features, you use use

    use std::net;
    use std::io::prelude::*;
    
Pocky answered 30/1, 2022 at 5:59 Comment(3)
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?Conclude
@RaleighL., if you you are inside a file, its create its own module. so inside a.rs you do not have to use mod. if in src folder, you create a.rs, you can use a module inside main.rs, u can write mod a. then if you want to reach functions inside module a you say use a::function1Pocky
@RaleighL. mod declaration is used if you are inside a file, (maybe in main.rs) and youwant to create a separate module. but if you create a new file, it creates its own module,Pocky
S
4

The mod statement tells the compiler about a file it hasn't seen before. The use statement lets you import things the compiler already knows about into the local scope.

Swell answered 23/10, 2023 at 9:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.