Step 3 of 7
use: shortcuts for long paths
Writing crate::restaurant::kitchen::cook over and over gets old. use creates a shortcut: a local name for a path, valid in the module where you write it.
mod shapes {
pub mod circle {
pub fn area(r: f64) -> f64 {
std::f64::consts::PI * r * r
}
}
pub mod square {
pub fn area(side: f64) -> f64 {
side * side
}
}
}
use shapes::circle;
use shapes::square::area as square_area;
use std::collections::{BTreeMap, HashSet};
fn main() {
println!("{:.2}", circle::area(1.0));
println!("{:.2}", square_area(3.0));
let mut stock = BTreeMap::new();
stock.insert("bolts", 40);
let mut seen = HashSet::new();
seen.insert("bolts");
println!("{} {}", stock.len(), seen.len());
}
3.14
9.00
1 1
| Form | Brings into scope |
|---|---|
use a::b::c; |
c |
use a::b::{c, d}; |
c and d (braces can nest: use std::{fmt, io::{self, Read}};) |
use a::b::{self, c}; |
b itself, and c |
use a::b::c as other; |
c, under the name other |
use a::b::*; |
everything public in b (a glob import) |
What reviewers expect
These are the conventions from the Rust book, and what a code review will push you toward:
- Functions: import the parent module and call
module::function():use std::io;thenio::stdin(). The call shows the function isn't local. - Types (structs, enums, traits): import the type itself:
use std::collections::HashMap;thenHashMap::new(). - Two things with the same name: keep their modules (
fmt::Resultvsio::Result), or rename one withas. - Globs: avoid them in normal code, since readers can't tell where names come from. They're fine for preludes (
use rayon::prelude::*;) and foruse super::*;in test modules. - Group
uselines at the top of the module;cargo fmtsorts them, and rust-analyzer can add them for you.
use is per module
A use only applies to the module it's written in. Modules inside it don't inherit it:
use std::collections::HashMap;
mod stats {
pub fn count(words: &[&str]) -> HashMap<String, usize> {
let mut counts = HashMap::new();
for w in words {
*counts.entry(w.to_string()).or_insert(0) += 1;
}
counts
}
}
fn main() {
println!("{}", stats::count(&["a", "b", "a"]).len());
}
error[E0425]: cannot find type `HashMap` in this scope
Move the use std::collections::HashMap; line inside mod stats, where the code that needs it is. (In the broken version, the compiler also warns that the root's use is unused: nothing at the root needs it.)
Your task
The main function uses Item, stock::restock, report::line and BTreeMap, but nothing brings them into scope. Add use lines (and don't change main or the modules) so the program compiles and prints:
bolts 55
Challenge 2
Two modules each have a function called distance. Add two use lines with as so main can call the metric one as km and the imperial one as miles. The program prints:
5.0 km
3.1 mi
Challenge 3
Finish the module stats: stats::word_counts(text: &str) -> BTreeMap<String, usize> counts how many times each word appears (split on whitespace, lowercase the words). The starter has a use line, but in the wrong place: move it to the top of mod stats (the first line inside its braces) so stats can name BTreeMap, then write the function.
Previous: Paths: crate, super and self Next: Struct fields, privacy and pub(crate)