Files
docs-rust/ch07/ch07-05-separating-modules-into-different-files.html
2026-06-22 21:27:36 +05:30

116 lines
7.1 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>Separating Modules into Different Files</title>
</head>
<body>
<h2 id="separating-modules-into-different-files"><a class="header" href="#separating-modules-into-different-files">Separating Modules into Different Files</a></h2>
<p>So far, all the examples in this chapter defined multiple modules in one file.
When modules get large, you might want to move their definitions to a separate
file to make the code easier to navigate.</p>
<p>For example, lets start from the code in Listing 7-17 that had multiple
restaurant modules. Well extract modules into files instead of having all the
modules defined in the crate root file. In this case, the crate root file is
<em>src/lib.rs</em>, but this procedure also works with binary crates whose crate root
file is <em>src/main.rs</em>.</p>
<p>First, well extract the <code>front_of_house</code> module to its own file. Remove the
code inside the curly brackets for the <code>front_of_house</code> module, leaving only
the <code>mod front_of_house;</code> declaration, so that <em>src/lib.rs</em> contains the code
shown in Listing 7-21. Note that this wont compile until we create the
<em>src/front_of_house.rs</em> file in Listing 7-22.</p>
<figure class="listing" id="listing-7-21">
<span class="file-name">Filename: src/lib.rs</span>
<pre><code class="language-rust ignore does_not_compile">mod front_of_house;
pub use crate::front_of_house::hosting;
pub fn eat_at_restaurant() {
hosting::add_to_waitlist();
}</code></pre>
<figcaption><a href="#listing-7-21">Listing 7-21</a>: Declaring the <code>front_of_house</code> module whose body will be in <em>src/front_of_house.rs</em></figcaption>
</figure>
<p>Next, place the code that was in the curly brackets into a new file named
<em>src/front_of_house.rs</em>, as shown in Listing 7-22. The compiler knows to look
in this file because it came across the module declaration in the crate root
with the name <code>front_of_house</code>.</p>
<figure class="listing" id="listing-7-22">
<span class="file-name">Filename: src/front_of_house.rs</span>
<pre><code class="language-rust ignore">pub mod hosting {
pub fn add_to_waitlist() {}
}</code></pre>
<figcaption><a href="#listing-7-22">Listing 7-22</a>: Definitions inside the <code>front_of_house</code> module in <em>src/front_of_house.rs</em></figcaption>
</figure>
<p>Note that you only need to load a file using a <code>mod</code> declaration <em>once</em> in your
module tree. Once the compiler knows the file is part of the project (and knows
where in the module tree the code resides because of where youve put the <code>mod</code>
statement), other files in your project should refer to the loaded files code
using a path to where it was declared, as covered in the <a href="ch07-03-paths-for-referring-to-an-item-in-the-module-tree.html">“Paths for Referring
to an Item in the Module Tree”</a><!-- ignore --> section. In other words,
<code>mod</code> is <em>not</em> an “include” operation that you may have seen in other
programming languages.</p>
<p>Next, well extract the <code>hosting</code> module to its own file. The process is a bit
different because <code>hosting</code> is a child module of <code>front_of_house</code>, not of the
root module. Well place the file for <code>hosting</code> in a new directory that will be
named for its ancestors in the module tree, in this case <em>src/front_of_house</em>.</p>
<p>To start moving <code>hosting</code>, we change <em>src/front_of_house.rs</em> to contain only
the declaration of the <code>hosting</code> module:</p>
<figure class="listing">
<span class="file-name">Filename: src/front_of_house.rs</span>
<pre><code class="language-rust ignore">pub mod hosting;</code></pre>
</figure>
<p>Then, we create a <em>src/front_of_house</em> directory and a <em>hosting.rs</em> file to
contain the definitions made in the <code>hosting</code> module:</p>
<figure class="listing">
<span class="file-name">Filename: src/front_of_house/hosting.rs</span>
<pre><code class="language-rust ignore">pub fn add_to_waitlist() {}</code></pre>
</figure>
<p>If we instead put <em>hosting.rs</em> in the <em>src</em> directory, the compiler would
expect the <em>hosting.rs</em> code to be in a <code>hosting</code> module declared in the crate
root and not declared as a child of the <code>front_of_house</code> module. The
compilers rules for which files to check for which modules code mean the
directories and files more closely match the module tree.</p>
<section class="note" aria-role="note">
<h3 id="alternate-file-paths"><a class="header" href="#alternate-file-paths">Alternate File Paths</a></h3>
<p>So far weve covered the most idiomatic file paths the Rust compiler uses,
but Rust also supports an older style of file path. For a module named
<code>front_of_house</code> declared in the crate root, the compiler will look for the
modules code in:</p>
<ul>
<li><em>src/front_of_house.rs</em> (what we covered)</li>
<li><em>src/front_of_house/mod.rs</em> (older style, still supported path)</li>
</ul>
<p>For a module named <code>hosting</code> that is a submodule of <code>front_of_house</code>, the
compiler will look for the modules code in:</p>
<ul>
<li><em>src/front_of_house/hosting.rs</em> (what we covered)</li>
<li><em>src/front_of_house/hosting/mod.rs</em> (older style, still supported path)</li>
</ul>
<p>If you use both styles for the same module, youll get a compiler error.
Using a mix of both styles for different modules in the same project is
allowed but might be confusing for people navigating your project.</p>
<p>The main downside to the style that uses files named <em>mod.rs</em> is that your
project can end up with many files named <em>mod.rs</em>, which can get confusing
when you have them open in your editor at the same time.</p>
</section>
<p>Weve moved each modules code to a separate file, and the module tree remains
the same. The function calls in <code>eat_at_restaurant</code> will work without any
modification, even though the definitions live in different files. This
technique lets you move modules to new files as they grow in size.</p>
<p>Note that the <code>pub use crate::front_of_house::hosting</code> statement in
<em>src/lib.rs</em> also hasnt changed, nor does <code>use</code> have any impact on what files
are compiled as part of the crate. The <code>mod</code> keyword declares modules, and Rust
looks in a file with the same name as the module for the code that goes into
that module.</p>
<h2 id="summary"><a class="header" href="#summary">Summary</a></h2>
<p>Rust lets you split a package into multiple crates and a crate into modules so
that you can refer to items defined in one module from another module. You can
do this by specifying absolute or relative paths. These paths can be brought
into scope with a <code>use</code> statement so that you can use a shorter path for
multiple uses of the item in that scope. Module code is private by default, but
you can make definitions public by adding the <code>pub</code> keyword.</p>
<p>In the next chapter, well look at some collection data structures in the
standard library that you can use in your neatly organized code.</p>
</body>
</html>