Walking through "The Java Tutorials" with Rust
Reading 'Object-Oriented Programming Concepts' with Rust in mind
Another weird evening in April 2021Out of the various lessons in "The Java Tutorials", the most interesting for me to try and follow with Rust is the first lesson of the trail "Learning the Java Language": "Object-Oriented Programming Concepts".
link: Object-Oriented Programming Concepts
My summary of the lesson above
The lesson:
-
Introduces the model of
Objects
that havestate
andbehavior
. -
Introduces Java classes as "blueprints of objects".
-
Example: After defining a Bicycle Class with some setters and print methods, demonstrating the creation of 2 Bicycle objects, updating their cadence, speed, and gear states, and lastly printing it.
class BicycleDemo {
public static void main(String[] args) {
// Create two different
// Bicycle objects
Bicycle bike1 = new Bicycle();
Bicycle bike2 = new Bicycle();
// Invoke methods on
// those objects
bike1.changeCadence(50);
bike1.speedUp(10);
bike1.changeGear(2);
bike1.printStates();
bike2.changeCadence(50);
bike2.speedUp(10);
bike2.changeGear(2);
bike2.changeCadence(40);
bike2.speedUp(10);
bike2.changeGear(3);
bike2.printStates();
}
}
Trying it with Rust
Well, looks like in Rust this could be directly translated to a Struct
that holds the state of an object and an Impl
block that defines the behavior of that object:
struct Bicycle {
cadence : i32,
speed: i32,
gear: i32
}
impl Bicycle {
fn change_cadence(&mut self, cadence : i32) {
self.cadence = cadence;
}
fn speed_up(&mut self, increment : i32) {
self.speed += increment;
}
fn change_gear(&mut self, gear : i32) {
self.gear = gear;
}
fn print_states(&self){
println!("cadence: {} speed: {} gear: {}", &self.cadence, &self.speed, &self.gear);
}
}
fn main() {
let mut bike1 = Bicycle { cadence: 0, speed: 0, gear: 0 };
let mut bike2 = Bicycle { cadence: 0, speed: 0, gear: 0 };
bike1.change_cadence(50);
bike1.speed_up(10);
bike1.change_gear(2);
bike1.print_states();
bike2.change_cadence(50);
bike2.speed_up(10);
bike2.change_gear(2);
bike2.change_cadence(40);
bike2.speed_up(10);
bike2.change_gear(3);
bike2.print_states();
// prints
// cadence: 50 speed: 10 gear: 2
// cadence: 40 speed: 20 gear: 3
}
So far so good :)
Comparing Java and Rust in the example above
Default constructor
- Rust doesn't have a built-in default constructor like java does.
- Rust standard library Default Trait defines what happens when
default()
is called to create a default instance of aStruct
. - One can use the derive macro to implemented it for a Struct with standard values for primitive types.
- If I wished a default
gear = 1
I'll have to impl theDefault
trait for Bicycle manually.
Mutability is explicit in Rust
- To enable the methods
change_cadence
,speed_up
, andchange_gear
to change the state of a Bicycle, the method signature must contain&mut self
(a mutable reference to self). In Java, for comparison, the keywordthis
is always there unless it's astatic
method. - This is also reflected in the caller site: to enable any state-changing method to be called on the
Bicycle
instancebike1
, we must declare it with themut
keyword.