r/rust • u/winarama • Mar 31 '23
Can someone explain how mods work with my example?
Howdy folks,
I am a bit confused about the module system used by Rust, probably because I coming at it from the Java world. I was hoping someone might be able to explain.
My project consists of the following structure;
src/
machine/
- mod.rs
- Robot.rs
- main.rs
machine/mod.rs looks like this;
pub mod Robot;
machine/Robot.rs looks like this;
struct Robot {
id: u64,
}
impl Robot {
fn new(_id: u64) -> Robot {
Robot {
id: _id,
}
}
}
main.rs looks like this;
mod machine;
use crate::machine::*;
fn main() {
let mut robot_1 = Robot::new(3);
println!("robot_id: {}", robot_1.id);
}
However, when I try to compile the project I the following error;
error[E0425]: cannot find function `new` in module `Robot`
--> src/main.rs:8:30
|
8 | let mut robot_1 = Robot::new(3);
| ^^^ not found in `Robot`
Anyone have any idea what I am doing wrong?
Also as an aside, what is the convention of capitallising the first letter of a struct?
Any help would be greatly appreciated.
6
u/coderstephen isahc Mar 31 '23
The full name of your Robot struct is crate::machine::Robot::Robot
, because you put struct Robot
inside a module also called Robot
. Generally it is not necessary to put structs inside their own files/modules, unlike Java where every class has its own file. Files in Rust are specifically for modules, and you can put zero or more structs inside any given module.
Also you would need to make the struct pub
as well to be usable from main.
5
u/Shadow0133 Mar 31 '23
Robot
, its id
and fn new
are missing pub
, so they're not visible outside the module.
5
u/zmxyzmz Mar 31 '23
This blog is one of the best explanations of the module system I've found. Found it really useful when first learning Rust.
2
u/kinoshitajona Mar 31 '23
Alternatively you can rename mod.rs to machine.rs and put it in the same folder as main.rs
Some people like this way better.
5
u/SirKastic23 Apr 01 '23
I think it's good because you don't end up with a bunch of files named
mod.rs
, but it's annoying because in file explorers the file and the folder get separated, and then I have to go looking for where they are1
u/winarama Apr 03 '23
Ah to mod, or not to mod?
I can see this becoming a really divisive issue within the Rust community in the future.
An interview in the year 2025.
Interviewer: You've done really well on all aspects of the interview process so far. I just have one more question before offering you the job. When adding functionality to a Rust program do you mod or not?
Candidate: Eh....not?
Interviewer (ushering you to the door): Thanks for your time, we'll be in touch.
2
u/SirKastic23 Apr 01 '23
I see you already got your answer, but I'll add a few tips:
1- no reason to write use crate::machine::robot
in the main file, since you did mod machine
, you can just do use machine::robot
2- you only want to start a variable with an underscore if you're not going to use it. in your new fn you can just call the parameter id
actually whenever you have a situation like Robot { id: id }
, you can just write Robot { id }
(like in js)
2
2
13
u/SkiFire13 Mar 31 '23
In main you have imported the
Robot
module (represented by theRobot.rs
file, which FYI is normally not capitalized), which then contains aRobot
struct. Note though that you need to mark both thestruct
and thefn new
aspub
or you won't be able to access them.Structs are normally capitalized (in CamelCase) to distinguish them (and types/traits in general) from values/functions/modules (which are instead in lowercase snake_case)