DEV Community

Cover image for [Rust Gudie] 7.4. Keyword Use Pt. 1 - Using Use and the As Keyword
SomeB1oody
SomeB1oody

Posted on

[Rust Gudie] 7.4. Keyword Use Pt. 1 - Using Use and the As Keyword

If you find this helpful, please like, bookmark, and follow. To keep learning along, follow this series.

7.4.1 The Role of use

The role of use is to bring a path into the current scope. The imported item still follows privacy rules, which means only public parts can be brought in and used.

7.4.2 Using use

Look at an example:

mod front_of_house {  
    pub mod hosting {  
        pub fn add_to_waitlist() { }  
        fn seat_at_table() { }  
    }  
}  

use crate::front_of_house::hosting;  

pub fn eat_at_restaurant() {  
    hosting::add_to_waitlist();  
}
Enter fullscreen mode Exit fullscreen mode

Here, we first declare a front_of_house module, and inside it we declare a public submodule hosting. Under hosting there are two functions: the public add_to_waitlist and the private seat_at_table.

Then we use the use keyword to bring the hosting submodule under front_of_house from crate (that is, the whole file) into the current scope. This is similar to creating a file link in a file system, and also somewhat like using namespace in C++.

After importing it this way, the name hosting can be used directly in the current scope, as if the hosting module had been defined at the crate root.

In the eat_at_restaurant function below, because hosting has already been brought into the current scope, when calling add_to_waitlist, you do not need to write an absolute path starting from crate, nor a relative path starting from front_of_house; you can start directly from hosting.

But note that the imported module still follows privacy rules, so the seat_at_table function still cannot be called.

use can use either an absolute path or a relative path. For example, the line above:

use crate::front_of_house::hosting; 
Enter fullscreen mode Exit fullscreen mode

can be changed to:

use front_of_house::hosting;
Enter fullscreen mode Exit fullscreen mode

In general, however, absolute paths are used more often.

7.4.3 use Conventions

In the example above, we imported only up to the use level, but the function we call is only add_to_waitlist. Can we import add_to_waitlist directly? Actually, yes:

mod front_of_house {  
    pub mod hosting {  
        pub fn add_to_waitlist() { }  
        fn seat_at_table() { }  
    }  
}  

use crate::front_of_house::hosting::add_to_waitlist;  

pub fn eat_at_restaurant() {  
    add_to_waitlist();  
}
Enter fullscreen mode Exit fullscreen mode

This is also fine, but it is not recommended.

If there is a lot of code, you may no longer know whether add_to_waitlist is defined locally or in another module. Therefore, for functions, the usual practice is to import their parent module and call the function through that parent module, to indicate that the function is not defined locally. But you only need to import up to the parent of the function; no need to import too much, otherwise there will be too much repeated typing.

For other items, such as structs and enums, it is generally better to import the full path, all the way to the item itself, rather than importing only the parent module. For example:

use std::collections::HashMap;  

fn main() {  
    let mut map = HashMap::new();  
    map.insert(1, 2);  
}
Enter fullscreen mode Exit fullscreen mode

When using the HashMap struct from the standard library’s collections module, you import the item itself directly. When using it, you refer to it simply as HashMap, without the parent module.

If there are items with the same name, whether they are functions or not, import them through their parent modules to distinguish them. For example:

use std::fmt;  
use std::io;  

fn f1() -> fmt::Result { }  

fn f2() -> io::Result { }

fn main() { }
Enter fullscreen mode Exit fullscreen mode

In this example (ignoring compilation issues; this is only a demonstration), I need both Result from fmt and Result from io, so I need to import the parent modules fmt and io.

If you do not want to write it this way, you can also use the as keyword.

7.4.4 The as Keyword

The as keyword can assign a local alias to an imported path. For example, let’s modify the example above:

use std::fmt::Result;  
use std::io::Result as IoResult;  

fn f1() -> Result { }  

fn f2() -> IoResult { }  
fn main() { }
Enter fullscreen mode Exit fullscreen mode

This way, you do not need to import only the parent module; you can import the item directly.

Top comments (0)