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.
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;
oruse 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:
extern crate
extern crate
fills the gap between Cargo and Rust. We write code in a .rs file, this file can be compiled withrustc
. Cargo will manage external dependencies and callrustc
. Theextern crate ...
line tells the compiler to look for this namespace, so it is unambiguous.mod
mod
has two uses:Modules can be:
use
use
imports a namespace. We are required to announce what are we going to use before using it. The use clause is pretty strict, if we stateuse module1::moduleA;
no other module frommodule1
will be available butmoduleA
. 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:
mod.rs contains:
main.rs contains:
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
.