The use keyword like in use game1::func2; imports a func2 function from the game1 module, so that it can simply be called with its name, func2(). You can even give it a shorter name with use game1::func2 as gf2; so that it can be called as gf2().
When the module game1 contains two (or more) functions, func2 and func3, that we want to import, this can be done with use game1::{func2, func3};.
If you want to import all (public) items of the module game1 you can do it with *:
use game1::*;
However, using such a global import is not best practice, except in modules for testing. The main reason is that a global import makes it harder to see where names are bound. Furthermore, they are forward-incompatible, since new upstream exports can clash with existing names.
Inside a module, self:: and super:: can be prepended to a path, like game1::func2, to distinguish, respectively, between a function in the current module itself and a function in the parent scope outside of the module:
self::game1::func2(); ::game1::func2(); // same thing as self:: super::game1::func2();
The use statements are preferably written at the top of the code file, so that they work for the whole of the code. If you prepend the use statement with a pub, then you export these definitions (in other words, you make them visible) to the super level, like this:
pub use game1::{func2, func3};
If the code is inside the current module, write this as:
use self::game1::{func2, func3};
In the previous example, the module was defined in the main source file itself; in most cases a module will be defined in another source file. How do we import such modules? In Rust, we can insert the entire contents of a module source file into the current file by declaring the module at the top of the code (but after any use statements) like this--mod modul1; optionally preceded by pub.
This statement will look for a file, modul1.rs, in the same folder as the current source file, and import its code in the current code inside a module, modul1. If a modul1.rs file is not found, it will look for a mod.rs file in a subfolder modul1, and insert its code.
If we write it as pub mod modul1, then everything from modul1 is accessible.
This is Rust's mechanism for constructing a main source file that imports the code of many other source files and can refer to them. The mechanism works in a hierarchical fashion, allowing the creation of complete trees containing source code.
Here is a simple example; import_modules.rs contains the following code:
// from Chapter 8/code/import_modules.rs mod modul1; mod modul2; fn main() { modul1::func1(); modul2::func1(); }
In a subfolder, modul1, we have the mod.rs file, containing this:
pub fn func1() { println!("called func1 from modul1"); }
The modul2.rs file in the same folder as import_modules.rs contains this:
pub fn func1() { println!("called func1 from modul2"); }
Executing import_modules prints out the following:
called func1 from modul1 called func1 from modul2
Compile import_modules.rs on the command-line with rustc, using the Sublime Text plugin, for example, it is not able to find the module code.
What happens if you simply call func1() in main()? Now the compiler doesn't know which func1 to call, either from modul1 or from modul2, resulting in error: unresolved name `func1`. But if we add usemodul1::func1, then calling func1() works and the ambiguity is resolved.