I can't find how to include (or import, inject, or some other word) a function from one file (module) to another.
I start a new project with
$ cd ~/projects $ cargo new proj --bin $ cd proj $ tree . | -- Cargo.toml -- src | -- main.rs
I modify main.rs
and create a new file a.rs
(inside the src
dir) with the following code:
main.rs
fn main() { println!("{}", a::foo()); }
a.rs
pub fn foo() -> i32 { 42 }
I run the project with cargo run
and get the error:
error[E0433]: failed to resolve: use of undeclared type or module `a` --> src/main.rs:2:20 | 2 | println!("{}", a::foo()); | ^ use of undeclared type or module `a`
It seems that I need to import the a
somehow. I tried to add following things as a first line to main.rs
use a;
error[E0432]: unresolved import `a` --> src/main.rs:1:5 | 1 | use a; | ^ no `a` in the root
use a::*;
error[E0432]: unresolved import `a` --> src/main.rs:1:5 | 1 | use a::*; | ^ maybe a missing `extern crate a;`? error[E0433]: failed to resolve: use of undeclared type or module `a` --> src/main.rs:4:20 | 4 | println!("{}", a::foo()); | ^ use of undeclared type or module `a`
use a::foo;
error[E0432]: unresolved import `a` --> src/main.rs:1:5 | 1 | use a::foo; | ^ maybe a missing `extern crate a;`? error[E0433]: failed to resolve: use of undeclared type or module `a` --> src/main.rs:4:20 | 4 | println!("{}", a::foo()); | ^ use of undeclared type or module `a`
extern crate a; use a::foo;
error[E0463]: can't find crate for `a` --> src/main.rs:1:1 | 1 | extern crate a; | ^^^^^^^^^^^^^^^ can't find crate
extern crate proj; use proj::a::foo;
error[E0463]: can't find crate for `proj` --> src/main.rs:1:1 | 1 | extern crate proj; | ^^^^^^^^^^^^^^^^^^ can't find crate
I have read the guide but still cannot figure out how to do imports.
To import the module, we use the keyword mod , followed by the file name without the . rs extension. When a module is imported, it allows us to use any code that's marked as public in the file we're importing the module from. Note that the module must be imported before we use any of its code.
The import statement allows you to import all the functions from a module into your code. Often, though, you'll only want to import a few functions, or just one. If this is the case, you can use the from statement.
You need to use the import keyword along with the desired module name. When interpreter comes across an import statement, it imports the module to your current program. You can use the functions inside a module by using a dot(.) operator along with the module name.
In a mainish module (main.rs, lib.rs, or subdir/mod.rs), you need to write mod a;
for all other modules that you want to use in your whole project (or in the subdir).
In any other module, you need to write use a;
or use a::foo;
You're far from the only person to be confused by this, and it's certainly possible to do better, but any changes to the module system will get rejected as "too confusing".
Edit: this answer was written for the "Rust 2015" language standard. Changes were made for the "Rust 2018" standard, see this blog post and the edition guide
In Rust, there are some keywords to deal with modules:
mod
mod
has two forms:
A module can be:
use
use
imports a name into the current module's namespace. We can use
any function, struct, enum, type alias, trait, or (sub)module. The use clause is pretty strict, if we state use module1::moduleA;
no other name from module1
will be available but moduleA
. An asterisk (*
) can be used to use everything within a module: use module1::*;
. Sets can be used as well: use module1::{moduleA, moduleB};
An example:
| main.rs |- module1 |- mod.rs |- moduleA.rs |- moduleB.rs
mod.rs contains:
pub mod moduleA; // declare a child module pub mod moduleB; // declare a child module
main.rs contains:
// use what Cargo downloaded (not necessary in Rust 2018) //extern crate that_one_thing_i_need; /// ====== mod module1; // declare a child module // some local stuff I want to scope mod local { pub fn my_function() {} } // ====== // make the symbols locally available: use module1::moduleA::*; use module1::moduleB::{functionX, moduleY, typeZ}; // To avoid having to write `that_one_thing_i_need::` a lot, // we can make local aliases that will be valid in the current module. use that_one_thing_i_need::fancy_stuff as fs; /// ====== fn main() { // we can use anything here from the namespaces we are using: // moduleA // functionX // moduleY // typeZ // fs // We can access stuff by navigating from the outermost visible // module name local::my_function(); }
Symbols are only usable from within the module. If you want to cross this barrier (even on a locally declared module) we need to make them public using the keyword pub
.
extern crate
extern crate
fills the gap between Cargo and Rust. We write code in a .rs file, this file can be compiled with rustc
. Cargo will manage external dependencies and call rustc
. The extern crate ...
line tells the compiler to look for this namespace, so it is unambiguous.
Editor's note —
extern crate
is not required in many cases if you are using the Rust 2018 edition.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With