Hi guys. I am from a C/C++ background. I just found out that the linking model of rust is very different from that of C/C++. In C/C++, you can call a function implemented in another file very easily, just declare it, and insert the implementation file into the project, and you are done. But in rust, if you need to call a function not in the same file, you need to import it from another crate. Therefore my question is how can I call a function in another file but in the same crate? Suppose now that we have two files, main.rs and sub.rs
main.rs
fn main() {
sub();
}
sub.rs
fn sub() {
println!("Hello world");
}
I want to know how to modify the two files so that they can both successfully compile. And how can I use rustc to link the two files and obtain main.exe? Please do not tell me I can use cargo, because cargo also does it by calling rustc.
Thanks!
3 Likes
In main.rs
, you need to declare sub.rs
as a module:
mod sub;
Note also that sub()
is currently private to its owning module (i.e. sub
). You need to make it public if you want it callable outside the sub
module: pub fn sub() {...}
.
Once you have that, you can then do:
fn main() {
sub::sub();
}
Alternatively, you can import just the sub
function itself:
mod sub;
use sub::sub;
fn main() {
sub();
}
As for rustc, you can run cargo
with a verbose flag (e.g. cargo build -v ...
) and then look at how it invokes rustc
.
6 Likes
I have tried according to your suggestions. But they still won't compile. Error message below:
D:\Computer\test\hello>edit src\main.rs
D:\Computer\test\hello>cargo build
Compiling hello v0.1.0 (file:///D:/Computer/test/hello)
error[E0423]: expected function, found module sub::sub
--> src\main.rs:4:5
|
4 | sub::sub();
| ^^^^^^^^ not a function
help: possible better candidate is found in another module, you can import it in
to scope
|
1 | use sub::sub::sub;
|
error[E0603]: module sub
is private
--> src\main.rs:4:5
|
4 | sub::sub();
| ^^^^^^^^
error: aborting due to 2 previous errors
error: Could not compile hello
.
To learn more, run the command again with --verbose.
D:\Computer\test\hello>
Is what you had in the original post the entire contents of each of those files? If not, can you paste exactly what you have?
1 Like
D:\Computer\test\hello>type src\main.rs
mod sub;
fn main() {
sub::sub();
}
D:\Computer\test\hello>type src\sub.rs
mod sub {
pub fn sub() {
println!("Hello, world!");
}
}
D:\Computer\test\hello>
In sub.rs
, you don't need the mod sub
there - the file is already a module called sub
by virtue of the file name being sub.rs
. What you have there creates two sub
modules, one nested within the other.
2 Likes
They now successfully compile! Thank you! Even the command does the job:
rustc main.rs
But how about if the project is a library? Because in a library there is no single clear entry point and rustc does not know which is the main file of the library.
The default main file of a library crate is lib.rs
, just like it is main.rs
for a binary crate.
2 Likes
@senator, you probably want to go back to The Book and read the modules section, that should explain everything for you.
2 Likes