Introduction
Hey there π
This article is about how I challenged new thing, learned its principal features, and succeeded less than a month.
As a software developer, I am always excited to try new technologies. Recently I decided to build a command-line to-do list application using Rust, despite having no prior experience with the language.
I had been looking for a simple, light and fast to-do app while coding and decided to create one by myself. Since I have used some services made with Rust,(like a code editor, formatter,etc.) and I know how fast they are. So I decided to use Rust.
I believe this project not only pushed up my skill but also showcased my ability to quickly adapt to new technologies.
Background
I started learning Rust less than a month ago, 100% self-studying using materials which are all made by Rust Official.
Project Overview
Nothing fancy in terms of features, you can display all remained tasks, add or delete a task.
The point is that all operations are done from a terminal.
Type one of the number from 1 to 4 for operation you desire e.g. Type 1 and display remained task.
Implementation
I utilize match { }
inside loop{ }
as flow of control for infinite loop unless user's input is 4, using module std::io
to detecte user input.
let mut input = String::new();
io::stdin().read_line(&mut input)?;
loop{
match input.trim(){
"1" => {
some_oparation();
continue,
},
"2" => {
.
.
.
"4" => {
end_oparation();
break;
},
_ => {
fall_back();
continue;
}
}
For now, the todo items are stored in a text file(if it doesn't exist, new txt file will be created).
What I succeeded and learned
I successfuly implemeneted basic feature of to-do from terminal.
It was a good experience to create with Rust. The thing I struggled with most of the time is ownership/borrowing.
Owenership
Ownership is a core concept and a set of rule in Rust that governs how memory is managed. Each value has an owner that is responsible for deallocating the value when it is no longer needed. There can be only one owner to each value. When the owner of a value goes out of scope, the value will be dropped.
//example 1 Ownership
{ //s is invalid at this line
//as it is not decleared yet
let s = "hello"; // s owns the string "hello" and s is now valid
let new_s = s; // the ownership of the string "hello" is transfered
//to variable new_s and s is no longer valid
} // this is end of scope and new_s is not valid anymore
*scope is block {}
Borrowing
Borrowing is a Rust's feature which lets you use values without taking ownership. You can use this by adding symbol &
before variable.
//example 2 Borrowing
fn main () {
let s = "hello";
print_string(&s);
print!("{}", s); // still available to use variable `s`
}
fn print_string (s:&str) {
print!("{} world", s); //display hello world in terminal
}
in example 2, &s
means borrowing the value of s
not taking ownership of it.
Not like example 1, variable s
is not reassigned to an another one, so it seems s
is still able to be used in print!()
(BTW this is same as console.log()
in Javascript/Typescript) without additional ampersands. It is needed. Passing a variable(not borrowing) to a function is similar to reassigning, so if you still need to use variable s
in same scope, one way it to pass a variable as reference to a function print_string()
Mutability
The default behavior of variable in Rust is immutable which is good in point of safety and concurrency, so what if you want to update the value in a variable like Example 3?
//Example 3 Mutability
fn main(){
let s = "hello";
print("{}", s);
s = "goodbye";
print("{}", s);
}
Example 3 is invalid. If you cargo run
(npm run
in Javascript) with the example 3, it would dislplay below error message.
error[E0384]: cannot assign twice to immutable variable `s`
--> src/main.rs:3:5
|
2 | let s = "hello";
| -
| |
| first assignment to `s`
| help: consider making this binding mutable: `mut s`
6 | s = "goodbye";
| ^^^^^^^^^^^^^ cannot assign twice to immutable variable
For more information about this error, try `rustc --explain E0384`.
warning: *** generated 1 warning
error: could not compile *** due to 1 previous error; 1 warning emitted
You might notice within error message, it sometimes gives us hint which saved me time during the project.(Be careful, it is just a hint, not an answer)
To fix the issue, you need to explicity tell Rust this variable is mutable using keyword mut
like below example 3-1
//Example 3-1 Mutability
fn main(){
let mut s = "hello";
print("{}", s);
s = "goodbye";
print("{}", s);
}
Why it is needed - Ownership and Borrowing
All programs have to manage how to use memory of computer while running. Some languages have garbage collector that regulary check memory which is no longer used while running. In Rust, memory is managed through this ownership concept. At the closing curly brackets, special function called drop
is automatically called. This is the timing where the owner of value returns the memory.
So no garbage collectoer or explicitly free memory execution is needed, it automatically frees memory when variables goes out of scope. This concept of Rust make it fast, memory-efficient and memory-safety yet flexible language.
Improvements
There are two things I would like to improve
Editing feature
The current features are adding, reading, and deleting, but you might forget which tasks are in progress and which are not if there are more than you can remember. It is nice to see progress, so I am planning to add editing feature so that a user can check whether remained tasks are in progress or haven't been started yet.
Refactor
With current implementation, a newly created task is saved to text file which is located in the root of working space(if not exist, new file would be created), which is not ideal in performance, scalability or data integrity perspectives. Instead it is better to implement storing data in database, like PostgreSQL or mySQL and I will change it soon.
Conclusion
Through this my first Rust project, even it is simple one, I felt how safe and fast the language is, and not 'that' hard to learn and create something with it. I was thinking this language was not for me, too difficult to learn until I started this project. If you haven't done anything with it and are looking for something new to learn, I would recommend Rust.
Thank you for reading so far, if you have any question or suggestion, please leave a comment or contanct me via Linkedin.
Top comments (0)