mirror of
https://github.com/darkicewolf50/RustBrock.git
synced 2025-06-15 13:04:18 -06:00
223 lines
6.7 KiB
Markdown
223 lines
6.7 KiB
Markdown
# Use
|
||
``use`` the keyword
|
||
This is used to bring paths into scope
|
||
``pub`` keyword is used to make items public
|
||
``as`` keyword for globs and external packages
|
||
|
||
# Modules
|
||
|
||
## Cheat Sheet
|
||
- **Start from the Root Crate**: compiler starts here to look for code to compile
|
||
- Normally src/main.rs for binary crates or src/lib.rs for library crates
|
||
- **Declaring Modules**: These are declared in the crate root file
|
||
- For example if you had a module called garden
|
||
- it would be declared by ``mod garden;``
|
||
- The complier would then look in these places
|
||
- Inline, within curly brackets that replace the semicolon following `mod garden`
|
||
- In the file _src/garden.rs_
|
||
- In the file _src/garden/mod.rs
|
||
- **Declaring submodules**: in any other file you can declare submodules in any other file than the root
|
||
- it would be declared by ``mod vegetables;``
|
||
- The complier would then look in these places for the submodule
|
||
- Inline, directly following `mod vegetables`, within curly brackets instead of the semicolon
|
||
- In the file _src/garden/vegetables.rs_
|
||
- In the file _src/garden/vegetables/mod.rs
|
||
- **Paths to code in Modules**: once a module is part of your crate, you can refer to the code in that module form anywhere else in that same crate as long as the privacy rules allow using that part of the code
|
||
- Example ``Asparagus`` is a struct/type in the graden vegetables module would be found at ``crate::graden::vegetables::Asparagus``
|
||
- **Private vs. public**: code is private by default to the parent module to make it public.
|
||
- To make a module public declare it with ``pub mod`` instead of ``mod``.
|
||
- To make items within the public module public as well add ``pub`` before their declaration
|
||
- **The ``use`` keyword**: This is used to shorten the full path to just the last ``::`` in the declaration
|
||
- example use
|
||
- ``crate::garden::vegetables::Asparagus``
|
||
- to now
|
||
- ``use crate::garden::vegetables::Asparagus;``
|
||
- now can call this module by just ``Asparagus``
|
||
|
||
Here is how this example's file directory would look
|
||
```
|
||
backyard
|
||
├── Cargo.lock
|
||
├── Cargo.toml
|
||
└── src
|
||
├── garden
|
||
│ └── vegetables.rs
|
||
├── garden.rs
|
||
└── main.rs
|
||
```
|
||
|
||
src/main.rs
|
||
```rust
|
||
use crate::garden::vegetables::Asparagus;
|
||
|
||
pub mod garden;
|
||
|
||
fn main() {
|
||
let plant = Asparagus {};
|
||
println!("I'm growing {plant:?}!");
|
||
}
|
||
```
|
||
|
||
src/garden.rs
|
||
```rust
|
||
pub mod vegetables;
|
||
```
|
||
|
||
src/garden/vegetables.rs
|
||
```rust
|
||
#[derive(Debug)]
|
||
pub struct Asparagus {}
|
||
```
|
||
|
||
## Grouping Related Code in Modules
|
||
used to group code together and make easier to reuse
|
||
modules allow for the control of privacy, implementations needs to be declared as public otherwise it will be private by default not available to other modules if private
|
||
|
||
public modules and implementations can allow for different code to depend on it
|
||
|
||
this should be used to organize code like a file directory
|
||
|
||
## Use with Modules
|
||
This is a quick way to bring into scope a module then refer to the public items associated with module
|
||
|
||
Use can be used with either the entire module or just one part of the module
|
||
|
||
```rust
|
||
use crate::example_mod::sub_mod;
|
||
use crate::example_mod::sub_mod::example_funct;
|
||
|
||
// --snip--
|
||
// consumption
|
||
sub_mod::example_funct();
|
||
example_funct();
|
||
```
|
||
|
||
The use statement must be in the module scope if defined in the same file
|
||
|
||
ex of proper use
|
||
```rust
|
||
mod another_mod {
|
||
use crate::example_mod::sub_mod::example_funct;
|
||
// --snip--
|
||
}
|
||
// dont do this but you can
|
||
use crate::example_mod::sub_mod::example_funct;
|
||
mod another_mod {
|
||
use super::example_funct;
|
||
super::example_funct();
|
||
// --snip--
|
||
}
|
||
```
|
||
|
||
ex not allowed
|
||
<img style="height:5svh" src="https://doc.rust-lang.org/book/img/ferris/does_not_compile.svg" />
|
||
```rust
|
||
use crate::example_mod::sub_mod::example_funct;
|
||
mod another_mod {
|
||
// --snip--
|
||
}
|
||
```
|
||
|
||
### Use the Idiomatic Path
|
||
``use crate::example_mod::sub_mod;`` this is the idiomatic path due to being able to call functions, structs, etc. inside the mod
|
||
|
||
``use crate::example_mod::sub_mod::mod_fn;``
|
||
this is not idiomatic due to specifying only one thing in the module
|
||
|
||
this is great for letting others know it is not defined in the same module/crate as where it is being called this is only for functions
|
||
|
||
for structs and enums it makes more sense to bring the whole object into scope then using the methods associated
|
||
|
||
this is just convention in rust
|
||
|
||
the exception to this convention is when bringing who items with the name name into scope because rust wont allow that and no one can read which call it is supposed to be
|
||
```rust
|
||
use std::fmt;
|
||
use std::io;
|
||
|
||
fn function1() -> fmt::Result {
|
||
// --snip--
|
||
}
|
||
|
||
fn function2() -> io::Result<()> {
|
||
// --snip--
|
||
}
|
||
```
|
||
|
||
Result makes no sense unless looking at input or slight differences
|
||
|
||
Then use the parent mod to do so if this is the case
|
||
|
||
### Providing New Names with the ``as`` Keyword
|
||
Here is the other solution to the similar names problem
|
||
```rust
|
||
use std::fmt::Result;
|
||
use std::io::Result as IoResult;
|
||
|
||
fn function1() -> Result {
|
||
// --snip--
|
||
}
|
||
|
||
fn function2() -> IoResult<()> {
|
||
// --snip--
|
||
}
|
||
```
|
||
|
||
as you can now see Result and IoResult may be called the same thing under the hood but now you can differentiate between the two
|
||
|
||
this is also an accepted convention in rust
|
||
|
||
### Re-exporting Names with ``pub use``
|
||
the name that is brough into scope with use is private, but you can make it public to the whole module then you can add pub before use
|
||
|
||
```rust
|
||
mod front_of_house {
|
||
pub mod hosting {
|
||
pub fn add_to_waitlist() {}
|
||
}
|
||
}
|
||
|
||
pub use crate::front_of_house::hosting;
|
||
|
||
pub fn eat_at_restaurant() {
|
||
hosting::add_to_waitlist();
|
||
}
|
||
```
|
||
|
||
this would be like defining it as if it was defining it in the scope that is desired
|
||
|
||
this also would have required front_of_house to also be marked public
|
||
|
||
this is useful when the internal structure of your code is different from how programmers would call your code
|
||
|
||
for example a customer would not think about frontend and backend they would think of add_to_waitlist and hosting not who's job it is
|
||
|
||
Will be added onto in ch 14
|
||
|
||
### Nested Paths/Shortening Use
|
||
this is a technique to shorten the use vertical space that it can often take up
|
||
|
||
```rust
|
||
use std::cmp::Ordering;
|
||
use std::io;
|
||
// this is the same as
|
||
use std::{cmp::Ordering, io};
|
||
```
|
||
|
||
this specifies a common path between the two
|
||
|
||
this can reduce the number of times that use shows up by A LOT
|
||
|
||
## Glob Operator on Use
|
||
Use if you want to bring all sub children of a path into scope
|
||
```rust
|
||
use std::collections::*;
|
||
```
|
||
This brings all public items defined in ``std::collections`` into the current scope
|
||
|
||
This makes it harder to tell what names are used in scope and where a name in used in your program
|
||
|
||
This is often used when testing to bring everything under test into the tests module
|
||
|
||
This is also used as part of the prelude pattern
|