RustBook/ch07-04-bringing-paths-into-scope-with-the-use-keyword.html

541 lines
42 KiB
HTML
Raw Normal View History

2020-01-06 20:57:15 +00:00
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Bringing Paths Into Scope with the use Keyword - The Rust Programming Language</title>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" />
<link rel="shortcut icon" href="favicon.png">
<link rel="stylesheet" href="css/variables.css">
<link rel="stylesheet" href="css/general.css">
<link rel="stylesheet" href="css/chrome.css">
<link rel="stylesheet" href="css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
<link href="googleFonts/css.css" rel="stylesheet" type="text/css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="ferris.css">
<link rel="stylesheet" href="theme/2018-edition.css">
</head>
<body>
<!-- Provide site root to javascript -->
<script type="text/javascript">
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "light" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script type="text/javascript">
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script type="text/javascript">
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('light')
html.classList.add(theme);
html.classList.add('js');
</script>
<!-- Hide / unhide sidebar before it is displayed -->
<script type="text/javascript">
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div id="sidebar-scrollbox" class="sidebar-scrollbox">
<ol class="chapter"><li class="expanded affix "><a href="title-page.html">The Rust Programming Language</a></li><li class="expanded affix "><a href="foreword.html">Foreword</a></li><li class="expanded affix "><a href="ch00-00-introduction.html">Introduction</a></li><li class="expanded "><a href="ch01-00-getting-started.html"><strong aria-hidden="true">1.</strong> Getting Started</a></li><li><ol class="section"><li class="expanded "><a href="ch01-01-installation.html"><strong aria-hidden="true">1.1.</strong> Installation</a></li><li class="expanded "><a href="ch01-02-hello-world.html"><strong aria-hidden="true">1.2.</strong> Hello, World!</a></li><li class="expanded "><a href="ch01-03-hello-cargo.html"><strong aria-hidden="true">1.3.</strong> Hello, Cargo!</a></li></ol></li><li class="expanded "><a href="ch02-00-guessing-game-tutorial.html"><strong aria-hidden="true">2.</strong> Programming a Guessing Game</a></li><li class="expanded "><a href="ch03-00-common-programming-concepts.html"><strong aria-hidden="true">3.</strong> Common Programming Concepts</a></li><li><ol class="section"><li class="expanded "><a href="ch03-01-variables-and-mutability.html"><strong aria-hidden="true">3.1.</strong> Variables and Mutability</a></li><li class="expanded "><a href="ch03-02-data-types.html"><strong aria-hidden="true">3.2.</strong> Data Types</a></li><li class="expanded "><a href="ch03-03-how-functions-work.html"><strong aria-hidden="true">3.3.</strong> Functions</a></li><li class="expanded "><a href="ch03-04-comments.html"><strong aria-hidden="true">3.4.</strong> Comments</a></li><li class="expanded "><a href="ch03-05-control-flow.html"><strong aria-hidden="true">3.5.</strong> Control Flow</a></li></ol></li><li class="expanded "><a href="ch04-00-understanding-ownership.html"><strong aria-hidden="true">4.</strong> Understanding Ownership</a></li><li><ol class="section"><li class="expanded "><a href="ch04-01-what-is-ownership.html"><strong aria-hidden="true">4.1.</strong> What is Ownership?</a></li><li class="expanded "><a href="ch04-02-references-and-borrowing.html"><strong aria-hidden="true">4.2.</strong> References and Borrowing</a></li><li class="expanded "><a href="ch04-03-slices.html"><strong aria-hidden="true">4.3.</strong> The Slice Type</a></li></ol></li><li class="expanded "><a href="ch05-00-structs.html"><strong aria-hidden="true">5.</strong> Using Structs to Structure Related Data</a></li><li><ol class="section"><li class="expanded "><a href="ch05-01-defining-structs.html"><strong aria-hidden="true">5.1.</strong> Defining and Instantiating Structs</a></li><li class="expanded "><a href="ch05-02-example-structs.html"><strong aria-hidden="true">5.2.</strong> An Example Program Using Structs</a></li><li class="expanded "><a href="ch05-03-method-syntax.html"><strong aria-hidden="true">5.3.</strong> Method Syntax</a></li></ol></li><li class="expanded "><a href="ch06-00-enums.html"><strong aria-hidden="true">6.</strong> Enums and Pattern Matching</a></li><li><ol class="section"><li class="expanded "><a href="ch06-01-defining-an-enum.html"><strong aria-hidden="true">6.1.</strong> Defining an Enum</a></li><li class="expanded "><a href="ch06-02-match.html"><strong aria-hidden="true">6.2.</strong> The match Control Flow Operator</a></li><li class="expanded "><a href="ch06-03-if-let.html"><strong aria-hidden="true">6.3.</strong> Concise Control Flow with if let</a></li></ol></li><li class="expanded "><a href="ch07-00-managing-growing-projects-with-packages-crates-and-modules.html"><strong aria-hidden="true">7.</strong> Managing Growing Projects with Packages, Crates, and Modules</a></li><li><ol class="section"><li class="expanded "><a href="ch07-01-packages-and-crates.html"><strong aria-hidden="true">7.1.</strong> Packages and Crates</a></li><li class="expanded "><a href="ch07-02-defining-modules-to-control-scope-and-privacy.html"><strong aria-hidden="true">7.2.</strong> Defining Modules to Control Scope and Privacy</a></li><li class="expanded "><a href="ch07-03-paths-for-referring-to-an-item-in-the-module-tree.html"><
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar" class="menu-bar">
<div id="menu-bar-sticky-container">
<div class="left-buttons">
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</button>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">The Rust Programming Language</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
</div>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" name="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script type="text/javascript">
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h2><a class="header" href="#bringing-paths-into-scope-with-the-use-keyword" id="bringing-paths-into-scope-with-the-use-keyword">Bringing Paths into Scope with the <code>use</code> Keyword</a></h2>
<p>It might seem like the paths weve written to call functions so far are
inconveniently long and repetitive. For example, in Listing 7-7, whether we
chose the absolute or relative path to the <code>add_to_waitlist</code> function, every
time we wanted to call <code>add_to_waitlist</code> we had to specify <code>front_of_house</code> and
<code>hosting</code> too. Fortunately, theres a way to simplify this process. We can
bring a path into a scope once and then call the items in that path as if
theyre local items with the <code>use</code> keyword.</p>
<p>In Listing 7-11, we bring the <code>crate::front_of_house::hosting</code> module into the
scope of the <code>eat_at_restaurant</code> function so we only have to specify
<code>hosting::add_to_waitlist</code> to call the <code>add_to_waitlist</code> function in
<code>eat_at_restaurant</code>.</p>
<p><span class="filename">Filename: src/lib.rs</span></p>
<pre><pre class="playpen"><code class="language-rust">mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
use crate::front_of_house::hosting;
pub fn eat_at_restaurant() {
hosting::add_to_waitlist();
hosting::add_to_waitlist();
hosting::add_to_waitlist();
}
<span class="boring">fn main() {}
</span></code></pre></pre>
<p><span class="caption">Listing 7-11: Bringing a module into scope with
<code>use</code></span></p>
<p>Adding <code>use</code> and a path in a scope is similar to creating a symbolic link in
the filesystem. By adding <code>use crate::front_of_house::hosting</code> in the crate
root, <code>hosting</code> is now a valid name in that scope, just as though the <code>hosting</code>
module had been defined in the crate root. Paths brought into scope with <code>use</code>
also check privacy, like any other paths.</p>
<p>You can also bring an item into scope with <code>use</code> and a relative path. Listing
7-12 shows how to specify a relative path to get the same behavior as in
Listing 7-11.</p>
<p><span class="filename">Filename: src/lib.rs</span></p>
<pre><pre class="playpen"><code class="language-rust">mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
use front_of_house::hosting;
pub fn eat_at_restaurant() {
hosting::add_to_waitlist();
hosting::add_to_waitlist();
hosting::add_to_waitlist();
}
<span class="boring">fn main() {}
</span></code></pre></pre>
<p><span class="caption">Listing 7-12: Bringing a module into scope with <code>use</code> and
a relative path</span></p>
<h3><a class="header" href="#creating-idiomatic-use-paths" id="creating-idiomatic-use-paths">Creating Idiomatic <code>use</code> Paths</a></h3>
<p>In Listing 7-11, you might have wondered why we specified <code>use crate::front_of_house::hosting</code> and then called <code>hosting::add_to_waitlist</code> in
<code>eat_at_restaurant</code> rather than specifying the <code>use</code> path all the way out to
the <code>add_to_waitlist</code> function to achieve the same result, as in Listing 7-13.</p>
<p><span class="filename">Filename: src/lib.rs</span></p>
<pre><pre class="playpen"><code class="language-rust">mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
use crate::front_of_house::hosting::add_to_waitlist;
pub fn eat_at_restaurant() {
add_to_waitlist();
add_to_waitlist();
add_to_waitlist();
}
<span class="boring">fn main() {}
</span></code></pre></pre>
<p><span class="caption">Listing 7-13: Bringing the <code>add_to_waitlist</code> function
into scope with <code>use</code>, which is unidiomatic</span></p>
<p>Although both Listing 7-11 and 7-13 accomplish the same task, Listing 7-11 is
the idiomatic way to bring a function into scope with <code>use</code>. Bringing the
functions parent module into scope with <code>use</code> so we have to specify the parent
module when calling the function makes it clear that the function isnt locally
defined while still minimizing repetition of the full path. The code in Listing
7-13 is unclear as to where <code>add_to_waitlist</code> is defined.</p>
<p>On the other hand, when bringing in structs, enums, and other items with <code>use</code>,
its idiomatic to specify the full path. Listing 7-14 shows the idiomatic way
to bring the standard librarys <code>HashMap</code> struct into the scope of a binary
crate.</p>
<p><span class="filename">Filename: src/main.rs</span></p>
<pre><pre class="playpen"><code class="language-rust">use std::collections::HashMap;
fn main() {
let mut map = HashMap::new();
map.insert(1, 2);
}
</code></pre></pre>
<p><span class="caption">Listing 7-14: Bringing <code>HashMap</code> into scope in an
idiomatic way</span></p>
<p>Theres no strong reason behind this idiom: its just the convention that has
emerged, and folks have gotten used to reading and writing Rust code this way.</p>
<p>The exception to this idiom is if were bringing two items with the same name
into scope with <code>use</code> statements, because Rust doesnt allow that. Listing 7-15
shows how to bring two <code>Result</code> types into scope that have the same name but
different parent modules and how to refer to them.</p>
<p><span class="filename">Filename: src/lib.rs</span></p>
<pre><pre class="playpen"><code class="language-rust">
<span class="boring">#![allow(unused_variables)]
</span><span class="boring">fn main() {
</span>use std::fmt;
use std::io;
fn function1() -&gt; fmt::Result {
// --snip--
<span class="boring"> Ok(())
</span>}
fn function2() -&gt; io::Result&lt;()&gt; {
// --snip--
<span class="boring"> Ok(())
</span>}
<span class="boring">}
</span></code></pre></pre>
<p><span class="caption">Listing 7-15: Bringing two types with the same name into
the same scope requires using their parent modules.</span></p>
<p>As you can see, using the parent modules distinguishes the two <code>Result</code> types.
If instead we specified <code>use std::fmt::Result</code> and <code>use std::io::Result</code>, wed
have two <code>Result</code> types in the same scope and Rust wouldnt know which one we
meant when we used <code>Result</code>.</p>
<h3><a class="header" href="#providing-new-names-with-the-as-keyword" id="providing-new-names-with-the-as-keyword">Providing New Names with the <code>as</code> Keyword</a></h3>
<p>Theres another solution to the problem of bringing two types of the same name
into the same scope with <code>use</code>: after the path, we can specify <code>as</code> and a new
local name, or alias, for the type. Listing 7-16 shows another way to write the
code in Listing 7-15 by renaming one of the two <code>Result</code> types using <code>as</code>.</p>
<p><span class="filename">Filename: src/lib.rs</span></p>
<pre><pre class="playpen"><code class="language-rust">
<span class="boring">#![allow(unused_variables)]
</span><span class="boring">fn main() {
</span>use std::fmt::Result;
use std::io::Result as IoResult;
fn function1() -&gt; Result {
// --snip--
<span class="boring"> Ok(())
</span>}
fn function2() -&gt; IoResult&lt;()&gt; {
// --snip--
<span class="boring"> Ok(())
</span>}
<span class="boring">}
</span></code></pre></pre>
<p><span class="caption">Listing 7-16: Renaming a type when its brought into
scope with the <code>as</code> keyword</span></p>
<p>In the second <code>use</code> statement, we chose the new name <code>IoResult</code> for the
<code>std::io::Result</code> type, which wont conflict with the <code>Result</code> from <code>std::fmt</code>
that weve also brought into scope. Listing 7-15 and Listing 7-16 are
considered idiomatic, so the choice is up to you!</p>
<h3><a class="header" href="#re-exporting-names-with-pub-use" id="re-exporting-names-with-pub-use">Re-exporting Names with <code>pub use</code></a></h3>
<p>When we bring a name into scope with the <code>use</code> keyword, the name available in
the new scope is private. To enable the code that calls our code to refer to
that name as if it had been defined in that codes scope, we can combine <code>pub</code>
and <code>use</code>. This technique is called <em>re-exporting</em> because were bringing
an item into scope but also making that item available for others to bring into
their scope.</p>
<p>Listing 7-17 shows the code in Listing 7-11 with <code>use</code> in the root module
changed to <code>pub use</code>.</p>
<p><span class="filename">Filename: src/lib.rs</span></p>
<pre><pre class="playpen"><code class="language-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();
hosting::add_to_waitlist();
hosting::add_to_waitlist();
}
<span class="boring">fn main() {}
</span></code></pre></pre>
<p><span class="caption">Listing 7-17: Making a name available for any code to use
from a new scope with <code>pub use</code></span></p>
<p>By using <code>pub use</code>, external code can now call the <code>add_to_waitlist</code> function
using <code>hosting::add_to_waitlist</code>. If we hadnt specified <code>pub use</code>, the
<code>eat_at_restaurant</code> function could call <code>hosting::add_to_waitlist</code> in its
scope, but external code couldnt take advantage of this new path.</p>
<p>Re-exporting is useful when the internal structure of your code is different
from how programmers calling your code would think about the domain. For
example, in this restaurant metaphor, the people running the restaurant think
about “front of house” and “back of house.” But customers visiting a restaurant
probably wont think about the parts of the restaurant in those terms. With
<code>pub use</code>, we can write our code with one structure but expose a different
structure. Doing so makes our library well organized for programmers working on
the library and programmers calling the library.</p>
<h3><a class="header" href="#using-external-packages" id="using-external-packages">Using External Packages</a></h3>
<p>In Chapter 2, we programmed a guessing game project that used an external
package called <code>rand</code> to get random numbers. To use <code>rand</code> in our project, we
added this line to <em>Cargo.toml</em>:</p>
<!-- When updating the version of `rand` used, also update the version of
`rand` used in these files so they all match:
* ch02-00-guessing-game-tutorial.md
* ch14-03-cargo-workspaces.md
-->
<p><span class="filename">Filename: Cargo.toml</span></p>
<pre><code class="language-toml">[dependencies]
rand = &quot;0.5.5&quot;
</code></pre>
<p>Adding <code>rand</code> as a dependency in <em>Cargo.toml</em> tells Cargo to download the
<code>rand</code> package and any dependencies from <a href="https://crates.io/">crates.io</a> and
make <code>rand</code> available to our project.</p>
<p>Then, to bring <code>rand</code> definitions into the scope of our package, we added a
<code>use</code> line starting with the name of the package, <code>rand</code>, and listed the items
we wanted to bring into scope. Recall that in the <a href="ch02-00-guessing-game-tutorial.html#generating-a-random-number">“Generating a Random
Number”</a><!-- ignore --> section in Chapter 2, we brought the <code>Rng</code> trait
into scope and called the <code>rand::thread_rng</code> function:</p>
<pre><code class="language-rust ignore">use rand::Rng;
fn main() {
let secret_number = rand::thread_rng().gen_range(1, 101);
}
</code></pre>
<p>Members of the Rust community have made many packages available at
<a href="https://crates.io/">crates.io</a>, and pulling any of them into your package
involves these same steps: listing them in your packages <em>Cargo.toml</em> file and
using <code>use</code> to bring items into scope.</p>
<p>Note that the standard library (<code>std</code>) is also a crate thats external to our
package. Because the standard library is shipped with the Rust language, we
dont need to change <em>Cargo.toml</em> to include <code>std</code>. But we do need to refer to
it with <code>use</code> to bring items from there into our packages scope. For example,
with <code>HashMap</code> we would use this line:</p>
<pre><pre class="playpen"><code class="language-rust">
<span class="boring">#![allow(unused_variables)]
</span><span class="boring">fn main() {
</span>use std::collections::HashMap;
<span class="boring">}
</span></code></pre></pre>
<p>This is an absolute path starting with <code>std</code>, the name of the standard library
crate.</p>
<h3><a class="header" href="#using-nested-paths-to-clean-up-large-use-lists" id="using-nested-paths-to-clean-up-large-use-lists">Using Nested Paths to Clean Up Large <code>use</code> Lists</a></h3>
<p>If were using multiple items defined in the same package or same module,
listing each item on its own line can take up a lot of vertical space in our
files. For example, these two <code>use</code> statements we had in the Guessing Game in
Listing 2-4 bring items from <code>std</code> into scope:</p>
<p><span class="filename">Filename: src/main.rs</span></p>
<pre><pre class="playpen"><code class="language-rust">
<span class="boring">#![allow(unused_variables)]
</span><span class="boring">fn main() {
</span>use std::io;
use std::cmp::Ordering;
// ---snip---
<span class="boring">}
</span></code></pre></pre>
<p>Instead, we can use nested paths to bring the same items into scope in one
line. We do this by specifying the common part of the path, followed by two
colons, and then curly brackets around a list of the parts of the paths that
differ, as shown in Listing 7-18.</p>
<p><span class="filename">Filename: src/main.rs</span></p>
<pre><pre class="playpen"><code class="language-rust">
<span class="boring">#![allow(unused_variables)]
</span><span class="boring">fn main() {
</span>use std::{cmp::Ordering, io};
// ---snip---
<span class="boring">}
</span></code></pre></pre>
<p><span class="caption">Listing 7-18: Specifying a nested path to bring multiple
items with the same prefix into scope</span></p>
<p>In bigger programs, bringing many items into scope from the same package or
module using nested paths can reduce the number of separate <code>use</code> statements
needed by a lot!</p>
<p>We can use a nested path at any level in a path, which is useful when combining
two <code>use</code> statements that share a subpath. For example, Listing 7-19 shows two
<code>use</code> statements: one that brings <code>std::io</code> into scope and one that brings
<code>std::io::Write</code> into scope.</p>
<p><span class="filename">Filename: src/lib.rs</span></p>
<pre><pre class="playpen"><code class="language-rust">
<span class="boring">#![allow(unused_variables)]
</span><span class="boring">fn main() {
</span>use std::io;
use std::io::Write;
<span class="boring">}
</span></code></pre></pre>
<p><span class="caption">Listing 7-19: Two <code>use</code> statements where one is a subpath
of the other</span></p>
<p>The common part of these two paths is <code>std::io</code>, and thats the complete first
path. To merge these two paths into one <code>use</code> statement, we can use <code>self</code> in
the nested path, as shown in Listing 7-20.</p>
<p><span class="filename">Filename: src/lib.rs</span></p>
<pre><pre class="playpen"><code class="language-rust">
<span class="boring">#![allow(unused_variables)]
</span><span class="boring">fn main() {
</span>use std::io::{self, Write};
<span class="boring">}
</span></code></pre></pre>
<p><span class="caption">Listing 7-20: Combining the paths in Listing 7-19 into
one <code>use</code> statement</span></p>
<p>This line brings <code>std::io</code> and <code>std::io::Write</code> into scope.</p>
<h3><a class="header" href="#the-glob-operator" id="the-glob-operator">The Glob Operator</a></h3>
<p>If we want to bring <em>all</em> public items defined in a path into scope, we can
specify that path followed by <code>*</code>, the glob operator:</p>
<pre><pre class="playpen"><code class="language-rust">
<span class="boring">#![allow(unused_variables)]
</span><span class="boring">fn main() {
</span>use std::collections::*;
<span class="boring">}
</span></code></pre></pre>
<p>This <code>use</code> statement brings all public items defined in <code>std::collections</code> into
the current scope. Be careful when using the glob operator! Glob can make it
harder to tell what names are in scope and where a name used in your program
was defined.</p>
<p>The glob operator is often used when testing to bring everything under test
into the <code>tests</code> module; well talk about that in the <a href="ch11-01-writing-tests.html#how-to-write-tests">“How to Write
Tests”</a><!-- ignore --> section in Chapter 11. The glob operator
is also sometimes used as part of the prelude pattern: see <a href="../std/prelude/index.html#other-preludes">the standard
library documentation</a><!-- ignore -->
for more information on that pattern.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="ch07-03-paths-for-referring-to-an-item-in-the-module-tree.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="ch07-05-separating-modules-into-different-files.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a href="ch07-03-paths-for-referring-to-an-item-in-the-module-tree.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a href="ch07-05-separating-modules-into-different-files.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script type="text/javascript">
window.playpen_copyable = true;
</script>
<script src="elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
<script src="mark.min.js" type="text/javascript" charset="utf-8"></script>
<script src="searcher.js" type="text/javascript" charset="utf-8"></script>
<script src="clipboard.min.js" type="text/javascript" charset="utf-8"></script>
<script src="highlight.js" type="text/javascript" charset="utf-8"></script>
<script src="book.js" type="text/javascript" charset="utf-8"></script>
<!-- Custom JS scripts -->
<script type="text/javascript" src="ferris.js"></script>
</body>
</html>