use Declarations

Within a scope, the use keyword creates shortcuts to items to reduce repetition of long paths.

Avoid Writing Full Paths with the use Keyword

book-rust-by-example-use

The use⮳ keyword creates a shortcut for a path. The shorter name can be used everywhere else in the scope.

//! This example demonstrates how to use the `use` keyword to bring items into
//! scope without having to write their full path.

/// Modules are used to organize code into logical units.
mod a {
    /// Nested module.
    /// We prefix `mod b` with `pub` to make it public.
    pub mod b {
        /// Public function.
        pub fn fn_in_b() {
            println!("in b!");
        }

        pub struct StructInB;
    }

    pub const CONST_IN_A: u8 = 1;
    pub type Point = (u8, u8);
}

// Bring the `b` module in scope with the `use` keyword.
use a::b;

// A relative path starts from the current module and uses
// `self`, or an identifier in the current module.
// You could also write: `use self::a::b;`.

fn main() {
    // Call the function using its full path.
    a::b::fn_in_b();

    // Call the function using its shortened path.
    b::fn_in_b();

    // Use declarations can exist inside of functions.
    // Bring the `StructInB` struct in scope, then refer to it via its short
    // name:
    use a::b::StructInB;
    let _ = StructInB;

    // Use declarations work for constants, type aliases, enums, statics,
    // traits, etc.
    use a::CONST_IN_A;
    let _ = CONST_IN_A;

    use a::Point;
    let _p: Point = (1, 2);
}

Bring an Item from an External Crate into Scope

To bring items from an external crate into scope, without having to write their full paths every time, write a use declaration with a path that begins with the external crate name. See also the Dependencies chapter.

//! This example demonstrates how to write `use` declarations to bring items
//! from external crates into scope, without having to write their full paths.

// Import a module from an external crate (here, `std`, the standard library),
// by writing a path that begins with the external crate name.
use std::array;
// That works as well for other items: types, traits, macros, etc.
// For example, import a struct from an external crate:
use std::collections::HashMap;

// With the above, `HashMap` can be used without prefix in the current
// module.

// You can prefix the path with `::`.
// This is useful to disambiguate between a local module and an external
// crate.
use ::anyhow::Result;

fn main() -> Result<()> {
    // Use a function from the `array` module of the `std` crate.
    // In this case, create an array of length 1 from a reference.
    let _arr = array::from_ref(&1);

    // Use `HashMap` from the `collections` module of the `std` crate.
    let _h: HashMap<String, String> = HashMap::new();

    // You can of course continue to refer to an item in an external crate by
    // its full path:
    let _h: HashMap<String, String> = std::collections::HashMap::new();

    Ok(())
}

/// A local module with the same name than an external crate.
mod anyhow {}

Bring a Function in Scope Idiomatically

It is idiomatic to bring the function's parent module into scope, not the function itself, then refer to the function via its shortened path a_module::a_function().

/// This module represents the front of the house in a restaurant.
mod front_of_house {
    /// This module handles hosting duties within the front of the house.
    pub mod hosting {
        /// Adds a customer to the waitlist.
        pub fn add_to_waitlist() {
            println!("Add to waitlist.");
        }
    }
}

// Bring the hosting module in scope.
use front_of_house::hosting;

fn eat_at_restaurant() {
    // We can now access the function within the `hosting` module,
    // without writing the whole path e.g.
    // `front_of_house::hosting::add_to_waitlist()`.
    //
    // IDIOM: we imported the module, not the function itself.
    hosting::add_to_waitlist();
}

fn main() {
    eat_at_restaurant();
}

Bring a Struct or Enum in Scope Idiomatically

On the other hand, when bringing in structs, enums, and other items in scope, it is idiomatic to specify the full path in the use statement and refer to the type via its name.

// This `use` statement allows us to use `HashMap` directly without having to
// specify its full path.
// IDIOM: we imported the `struct` itself, not its parent module.
use std::collections::HashMap;

// `HashMap` is declared in the standard library (`std`), which is an external
// crate. We therefore prefix the path with the crate's name.

fn main() {
    // We now refer to `HashMap` by its name.
    let mut mymap: HashMap<u32, String> = HashMap::new();

    // Let's add something to it then print...
    mymap.entry(42).or_insert("my favorite number".into());
    println!("{:?}", mymap);
}

Note: Rust doesn't allow importing two items with the same name into one scope. In that case, bring their modules into scope or write their full paths.

Reexport Items with pub use

use declarations are private to their containing module by default. A use declaration can be made public by the pub keyword. Such a declaration re-exports a name. See also the Visibility chapter.

mod a_module {
    mod private_module {
        pub fn public_function() {}
    }

    // The following `use` declaration brings `private_module::public_function`
    // into scope, with the `public_function` name.
    // Since `use` is preceded by `pub`, the `public_function` name is public.
    pub use private_module::public_function;
    // You can rename the item that is re-exported:
    pub use private_module::public_function as another_name;
}

fn main() {
    // `private_module` is... private, therefore the inner function is not
    // accessible.
    // ERROR: a_module::private_module::public_function();

    // However, the re-exported name is accessible.
    a_module::public_function();

    // Access the re-exported item via its alternate name.
    a_module::another_name();

    // Notes:
    // - Re-exports hide implementation details and flatten the module
    //   hierarchy. `public_function` appears as if it were declared in
    //   `a_module`.
    // - `a_module`, while private, is accessible, because `main` is in the same
    //   module.
}

Make use Declarations More Compact

Use declarations support a number of convenient shortcuts. You may use globs, define aliases, and combine multiple use statements.

#![allow(unused_imports)]

// Use a glob (the `*`) to bring all public objects within a module
// (here `default`) in scope. Use sparingly.
use std::default::*;
// The most common use of globs is to import a "prelude", a group of items
// commonly used together. See the "code organization" chapter.
use std::io::prelude::*;
// You can combine multiple `use` lines together with { }.
use std::io::{Read, Write};
// Idiom: use `self` to refer to the module itself.
// The following is equivalent to `use std::iter; use std::iter::empty;`.
use std::iter::{self, empty};
// Use `as` to define aliases, for example in case of name conflict.
use std::mem::drop as destruct;

fn main() {
    // Use `std::default::Default` without writing down the whole path,
    // because we imported all public objects from the `default` module.
    let v: Vec<u8> = Default::default();

    // Use the alias defined above:
    destruct(v);
}

Note that, while these shortcuts make your code more compact and readable, they can be inconvenient during early development, when you need to add or remove use statements frequently. Consider adding a rustfmt.toml configuration file to your project and adding imports_granularity = "Item" to flatten imports, so that each has its own use statement.

References