Files
docs-rust/ch07/ch07-02-defining-modules-to-control-scope-and-privacy.html
2026-06-22 21:27:36 +05:30

176 lines
9.5 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Control Scope and Privacy with Modules</title>
</head>
<body>
<!-- Old headings. Do not remove or links may break. -->
<p><a id="defining-modules-to-control-scope-and-privacy"></a></p>
<h2 id="control-scope-and-privacy-with-modules"><a class="header" href="#control-scope-and-privacy-with-modules">Control Scope and Privacy with Modules</a></h2>
<p>In this section, well talk about modules and other parts of the module system,
namely <em>paths</em>, which allow you to name items; the <code>use</code> keyword that brings a
path into scope; and the <code>pub</code> keyword to make items public. Well also discuss
the <code>as</code> keyword, external packages, and the glob operator.</p>
<h3 id="modules-cheat-sheet"><a class="header" href="#modules-cheat-sheet">Modules Cheat Sheet</a></h3>
<p>Before we get to the details of modules and paths, here we provide a quick
reference on how modules, paths, the <code>use</code> keyword, and the <code>pub</code> keyword work
in the compiler, and how most developers organize their code. Well be going
through examples of each of these rules throughout this chapter, but this is a
great place to refer to as a reminder of how modules work.</p>
<ul>
<li><strong>Start from the crate root</strong>: When compiling a crate, the compiler first
looks in the crate root file (usually <em>src/lib.rs</em> for a library crate and
<em>src/main.rs</em> for a binary crate) for code to compile.</li>
<li><strong>Declaring modules</strong>: In the crate root file, you can declare new modules;
say you declare a “garden” module with <code>mod garden;</code>. The compiler will look
for the modules code in these places:
<ul>
<li>Inline, within curly brackets that replace the semicolon following <code>mod garden</code></li>
<li>In the file <em>src/garden.rs</em></li>
<li>In the file <em>src/garden/mod.rs</em></li>
</ul>
</li>
<li><strong>Declaring submodules</strong>: In any file other than the crate root, you can
declare submodules. For example, you might declare <code>mod vegetables;</code> in
<em>src/garden.rs</em>. The compiler will look for the submodules code within the
directory named for the parent module in these places:
<ul>
<li>Inline, directly following <code>mod vegetables</code>, within curly brackets instead
of the semicolon</li>
<li>In the file <em>src/garden/vegetables.rs</em></li>
<li>In the file <em>src/garden/vegetables/mod.rs</em></li>
</ul>
</li>
<li><strong>Paths to code in modules</strong>: Once a module is part of your crate, you can
refer to code in that module from anywhere else in that same crate, as long
as the privacy rules allow, using the path to the code. For example, an
<code>Asparagus</code> type in the garden vegetables module would be found at
<code>crate::garden::vegetables::Asparagus</code>.</li>
<li><strong>Private vs. public</strong>: Code within a module is private from its parent
modules by default. To make a module public, declare it with <code>pub mod</code>
instead of <code>mod</code>. To make items within a public module public as well, use
<code>pub</code> before their declarations.</li>
<li><strong>The <code>use</code> keyword</strong>: Within a scope, the <code>use</code> keyword creates shortcuts to
items to reduce repetition of long paths. In any scope that can refer to
<code>crate::garden::vegetables::Asparagus</code>, you can create a shortcut with <code>use crate::garden::vegetables::Asparagus;</code>, and from then on you only need to
write <code>Asparagus</code> to make use of that type in the scope.</li>
</ul>
<p>Here, we create a binary crate named <code>backyard</code> that illustrates these rules.
The crates directory, also named <em>backyard</em>, contains these files and
directories:</p>
<pre><code class="language-text">backyard
├── Cargo.lock
├── Cargo.toml
└── src
├── garden
│   └── vegetables.rs
├── garden.rs
└── main.rs
</code></pre>
<p>The crate root file in this case is <em>src/main.rs</em>, and it contains:</p>
<figure class="listing">
<span class="file-name">Filename: src/main.rs</span>
<pre><code class="language-rust noplayground ignore">use crate::garden::vegetables::Asparagus;
pub mod garden;
fn main() {
let plant = Asparagus {};
println!("I'm growing {plant:?}!");
}</code></pre>
</figure>
<p>The <code>pub mod garden;</code> line tells the compiler to include the code it finds in
<em>src/garden.rs</em>, which is:</p>
<figure class="listing">
<span class="file-name">Filename: src/garden.rs</span>
<pre><code class="language-rust noplayground ignore">pub mod vegetables;</code></pre>
</figure>
<p>Here, <code>pub mod vegetables;</code> means the code in <em>src/garden/vegetables.rs</em> is
included too. That code is:</p>
<pre><code class="language-rust noplayground ignore">#[derive(Debug)]
pub struct Asparagus {}</code></pre>
<p>Now lets get into the details of these rules and demonstrate them in action!</p>
<h3 id="grouping-related-code-in-modules"><a class="header" href="#grouping-related-code-in-modules">Grouping Related Code in Modules</a></h3>
<p><em>Modules</em> let us organize code within a crate for readability and easy reuse.
Modules also allow us to control the <em>privacy</em> of items because code within a
module is private by default. Private items are internal implementation details
not available for outside use. We can choose to make modules and the items
within them public, which exposes them to allow external code to use and depend
on them.</p>
<p>As an example, lets write a library crate that provides the functionality of a
restaurant. Well define the signatures of functions but leave their bodies
empty to concentrate on the organization of the code rather than the
implementation of a restaurant.</p>
<p>In the restaurant industry, some parts of a restaurant are referred to as front
of house and others as back of house. <em>Front of house</em> is where customers are;
this encompasses where the hosts seat customers, servers take orders and
payment, and bartenders make drinks. <em>Back of house</em> is where the chefs and
cooks work in the kitchen, dishwashers clean up, and managers do administrative
work.</p>
<p>To structure our crate in this way, we can organize its functions into nested
modules. Create a new library named <code>restaurant</code> by running <code>cargo new restaurant --lib</code>. Then, enter the code in Listing 7-1 into <em>src/lib.rs</em> to
define some modules and function signatures; this code is the front of house
section.</p>
<figure class="listing" id="listing-7-1">
<span class="file-name">Filename: src/lib.rs</span>
<pre><code class="language-rust noplayground">mod front_of_house {
mod hosting {
fn add_to_waitlist() {}
fn seat_at_table() {}
}
mod serving {
fn take_order() {}
fn serve_order() {}
fn take_payment() {}
}
}</code></pre>
<figcaption><a href="#listing-7-1">Listing 7-1</a>: A <code>front_of_house</code> module containing other modules that then contain functions</figcaption>
</figure>
<p>We define a module with the <code>mod</code> keyword followed by the name of the module
(in this case, <code>front_of_house</code>). The body of the module then goes inside curly
brackets. Inside modules, we can place other modules, as in this case with the
modules <code>hosting</code> and <code>serving</code>. Modules can also hold definitions for other
items, such as structs, enums, constants, traits, and as in Listing 7-1,
functions.</p>
<p>By using modules, we can group related definitions together and name why
theyre related. Programmers using this code can navigate the code based on the
groups rather than having to read through all the definitions, making it easier
to find the definitions relevant to them. Programmers adding new functionality
to this code would know where to place the code to keep the program organized.</p>
<p>Earlier, we mentioned that <em>src/main.rs</em> and <em>src/lib.rs</em> are called <em>crate
roots</em>. The reason for their name is that the contents of either of these two
files form a module named <code>crate</code> at the root of the crates module structure,
known as the <em>module tree</em>.</p>
<p>Listing 7-2 shows the module tree for the structure in Listing 7-1.</p>
<figure class="listing" id="listing-7-2">
<pre><code class="language-text">crate
└── front_of_house
├── hosting
│ ├── add_to_waitlist
│ └── seat_at_table
└── serving
├── take_order
├── serve_order
└── take_payment
</code></pre>
<figcaption><a href="#listing-7-2">Listing 7-2</a>: The module tree for the code in Listing 7-1</figcaption>
</figure>
<p>This tree shows how some of the modules nest inside other modules; for example,
<code>hosting</code> nests inside <code>front_of_house</code>. The tree also shows that some modules
are <em>siblings</em>, meaning theyre defined in the same module; <code>hosting</code> and
<code>serving</code> are siblings defined within <code>front_of_house</code>. If module A is
contained inside module B, we say that module A is the <em>child</em> of module B and
that module B is the <em>parent</em> of module A. Notice that the entire module tree
is rooted under the implicit module named <code>crate</code>.</p>
<p>The module tree might remind you of the filesystems directory tree on your
computer; this is a very apt comparison! Just like directories in a filesystem,
you use modules to organize your code. And just like files in a directory, we
need a way to find our modules.</p>
</body>
</html>