RustArena

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:

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)