DailyCode 20
DailyCode 20
Preface
Phrase #1
Phrase #2
Phrase #3
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 1/43
09/06/2024, 16:00 DailyCode
Syllabus
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 2/43
09/06/2024, 16:00 DailyCode
Rust
Generally faster
Rust has a separate compilation step (similar to C++) that spits out an optimised binary and
does a lot of static analysis at compile time.
JS does JIT compilation.
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 4/43
Concurrency
09/06/2024, 16:00 DailyCode
Rust has built-in support for concurrent programming allowing multiple threads to perform
tasks simultaneously without risking data races
Javascript is single threaded generally (there are some projects that tried making it multi
threaded but rarely used)
Memory safe
Rust has a concept of owners, borrowing and lifetimes that make it extremely memory safe
💡 Rust doesn't hide complexity from developers it offers them the right tools to manage
all the complexity.
For this bootcamp, we’ll be getting comfortable with the syntax of Rust.
For most of the video, a repl.it playground should be good enough https://replit.com/~
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 5/43
09/06/2024, 16:00 DailyCode
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 6/43
09/06/2024, 16:00 DailyCode
lib vs application
Application
This would initialize a library that you can deploy for other people to use
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 7/43
09/06/2024, 16:00 DailyCode
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 8/43
09/06/2024, 16:00 DailyCode
main();
💡 Ignore how the printing is happening right now, we’ll come to it later
Equivalent typescript code
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 9/43
09/06/2024, 16:00 DailyCode
Copy
function main() {
let x: number = 1;
console.log(x);
}
main()
2. Booleans
Bools can have two states, true or false
Copy
fn main() {
let is_male = false;
let is_above_18 = true;
if is_male {
println!("You are a male");
} else {
println!("You are not a male");
}
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 10/43
09/06/2024, 16:00 DailyCode
if (is_male) {
console.log("You are a male");
} else {
console.log("You are not a male");
}
main();
3. Strings
There are two ways of doing strings in rust. We’ll be focussing on the easier one
Copy
fn main() {
let greeting = String::from("hello world");
println!("{}", greeting);
// print!("{}", greeting.chars().nth(1000))
}
// console.log(greeting[1000]);
}
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 11/43
Conditionals, loops…
09/06/2024, 16:00 DailyCode
Conditionals
Copy
pub fn main() {
let x = 99;
let is_even = is_even(x);
if is_even {
print!("{} is even", x);
} else {
print!("{} is odd", x);
}
}
Loops
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 12/43
09/06/2024, 16:00 DailyCode
Copy
pub fn main() {
let str = String::from("harkirat singh");
println!("First name {}", get_first_name(str))
Functions
Copy
fn do_sum(a: i32, b: i32) -> i32 {
return a + b;
}
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 13/43
09/06/2024, 16:00 DailyCode
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 14/43
09/06/2024, 16:00 DailyCode
Whenever you run a program (C++, Rust, JS), it allocates and deallocates memory on the
RAM.
For example, for the following JS code
Copy
function main() {
runLoop();
}
function runLoop() {
let x = [];
for (let i = 0; i < 100000; i++) {
x.push(1);
}
console.log(x);
}
main();
as the runLoop function runs, a new array is pushed to RAM, and eventually garbage
collected
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 15/43
09/06/2024, 16:00 DailyCode
Jargon #0 - Mutability
Memory management is a crucial aspect of programming in Rust, designed to ensure safety
and efficiency without the need for a garbage collector.
Not having a garbage collector is one of the key reasons rust is so fast
It achieves this using the
Mutability
1. Mutabilityvariables represent variables whose value cant be changed once assigned
Immutable
2. Heap and memory Copy
3. Ownership
fn main() {
model
let x: i32 = 1;
4. Borrowing
x = 2;and//references
Error because x is immutable
println!("{}", x);
5. Lifetimes
}
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 16/43
09/06/2024, 16:00 DailyCode
💡 const in Javascript is not the same as immutable variables in rust. In JS, you can still
update the contents of const and arrays objects
💡 JShttps://www.npmjs.com/package/immutable
also has a concept of immutability that a lot of libraries were built on in the past -
Examples
Hello world with numbers
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 18/43
09/06/2024, 16:00 DailyCode
Memory in action
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 19/43
09/06/2024, 16:00 DailyCode
Copy
fn main() {
stack_fn(); // Call the function that uses stack memory
heap_fn(); // Call the function that uses heap memory
update_string(); // Call the function that changes size of variable
}
fn stack_fn() {
// Declare a few integers on the stack
let a = 10;
let b = 20;
let c = a + b;
println!("Stack function: The sum of {} and {} is {}", a, b, c);
}
fn heap_fn() {
// Create a string, which is allocated on the heap
let s1 = String::from("Hello");
let s2 = String::from("World");
let combined = format!("{} {}", s1, s2);
println!("Heap function: Combined string is '{}'", combined);
}
fn update_string() {
// Start with a base string on the heap
let mut s = String::from("Initial string");
println!("Before update: {}", s);
Jargon #2 - Ownership
Ref - https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 20/43
09/06/2024, 16:00 DailyCode
Meet Rihana
She always wants to keep a boyfriend (or owner) and can never remain single. She says if I
ever become single (have no owners), I will die. She also can only have a single boyfriend at a
time.
Stack variables
Example #1 - Passing stack Variables inside functions
Copy
fn main() {
let x = 1; // crated on stack
let y = 3; // created on stack
println!("{}", sum(x, y));
println!("Hello, world!");
}
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 21/43
09/06/2024, 16:00 DailyCode
This might sound trivial since if the function is popped of the stack, all variables go away with
it, but check the next example
Example #2 - Scoping variables in the same fn
Copy
fn main() {
let x = 1; // crated on stack
{
let y = 3; // created on stack
}
Heap variables
Heap variables are like Rihana. They always want to have a single owner, and if their owner
goes out of scope, they get deallocated.
Any time the owner of a heap variable goes out of scope, the value is de-allocated from the
heap.
Example #1 - Passing strings (heap variables) to functions as args
Copy
fn main() {
let s1 = String::from("hello");
let s2 = s1;
println!("{}", s1); // This line would cause a compile error because
}
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 22/43
09/06/2024, 16:00 DailyCode
s1
name value
ptr
len 5
capacity 5 index value
0 h
s2 1 e
name value 2 l
ptr 3 l
len 5 4 o
capacity 5
fn takes_ownership(some_string: String) {
println!("{}", some_string); // `some_string` now owns the data.
}
At any time, each value can have a single owner. This is to avoid memory issues like
1. Double free error.
2. Dangling pointers.
Fix?
Clone the string
Copy
fn main() {
let s1 = String::from("hello");
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 23/43
09/06/2024, 16:00 DailyCode
let s2 = s1.clone();
println!("{}", s1); // Compiles now
}
But what if you want to pass the same string over to the function? You don’t want to clone it,
and you want to return back ownership to the original function?
You can either do the following -
Copy
fn main() {
let s1 = String::from("hello");
let s2 = takes_ownership(s1);
println!("{}", s2);
}
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 24/43
09/06/2024, 16:00 DailyCode
Rihana upgrades
Rihana now says I’d like to be borrowed from time to time. I will still have a single owner , but
I can still be borrowed by other variables temporarily. What rules do you think should apply to
her?
1. She can be borrowed by multiple people that she’s friends with but does no hanky panky
2. If she does want to do hanky panky, she can only have 1 borrower that she does it with.
She cant simultaneously be with other borrowers (even with no hanky panky)
References
References mean giving the address of a string rather than the ownership of the string over to
a function
For example
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 25/43
09/06/2024, 16:00 DailyCode
Copy
fn main() {
let s1 = String::from("Hello");
let s2 = &s1;
println!("{}", s2);
println!("{}", s1); // This is valid, The first pointer wasn't in
}
Borrowing
You can transferring ownership of variables to fns. By passing a reference to the string to the
function take_ownership , the ownership of the string remains with the original variable, in the
main function. This allows you to use my_string again after the function call.
Copy
fn main() {
let my_string = String::from("Hello, Rust!");
takes_ownership(&my_string); // Pass a reference to my_string
println!("{}", my_string); // This is valid because ownership was
}
fn takes_ownership(some_string: &String) {
println!("{}", some_string); // some_string is borrowed and not mov
}
Mutable references
What if you want a function to update the value of a variable?
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 26/43
09/06/2024, 16:00 DailyCode
Copy
fn main() {
let mut s1 = String::from("Hello");
update_word(&mut s1);
println!("{}", s1);
}
Try having more than one mutable reference at the same time -
Copy
fn main() {
let mut s1 = String::from("Hello");
let s2 = &mut s1;
update_word(&mut s1);
println!("{}", s1);
println!("{}", s2);
}
Rules of borrowing
There can me many immutable references at the same time
Copy
fn main() {
let s1 = String::from("Hello");
let s2 = &s1;
let s3 = &s1;
println!("{}", s1);
println!("{}", s2);
println!("{}", s3);
}
// No errors
Copy
fn main() {
let mut s1 = String::from("Hello");
let s2 = &mut s1;
let s3 = update_word(&mut s1);
println!("{}", s1);
println!("{}", s2);
}
If there is a mutable reference , you can’t have another immutable reference either.
Copy
fn main() {
let mut s1 = String::from("Hello");
let s2 = &mut s1;
let s3 = &s1;
println!("{}", s1);
println!("{}", s2);
}
💡 Two
now
good things to discuss at this point should be but we’re going to ignore it for
1. Lifetimes
2. String slices (&str)
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 28/43
09/06/2024, 16:00 DailyCode
Ref - https://doc.rust-lang.org/book/ch04-03-slices.html
Structs
Structs in rust let you structure data together. Similar to objects in javascript
Copy
struct User {
active: bool,
username: String,
email: String,
sign_in_count: u64,
}
fn main() {
let user1 = User {
active: true,
username: String::from("someusername123"),
email: String::from("[email protected]"),
sign_in_count: 1,
};
print!("User 1 username: {:?}", user1.username);
}
fn main() {
let mut user1 = User {
active: true,
sign_in_count: 1,
};
print_name(user1);
print!("User 1 username: {}", user1.active); // Error - can not use
}
fn print_name(user1: User) {
print!("User 1 username: {}", user1.active);
}
fn main() {
let mut user1 = User {
active: true,
sign_in_count: 1,
};
print_name(user1);
print!("User 1 username: {}", user1.active); // Error goes away beca
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 30/43
09/06/2024, 16:00 DailyCode
fn print_name(user1: User) {
print!("User 1 username: {}", user1.active);
}
fn main() {
let mut user1 = User {
active: true,
sign_in_count: 1,
username: "harkirat".to_string()
};
change_name(user1);
print!("User 1 username: {}", user1.active); // Error - can not use
}
fn change_name(user1: User) {
print!("User 1 username: {:?}", user1.active);
}
Try adding the Copy trait (you wont be able to because strings dont implement them, use
clone trait instead)
Copy
#[derive(Clone)]
struct User {
active: bool,
sign_in_count: u64,
username: String,
}
fn main() {
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 31/43
09/06/2024, 16:00 DailyCode
change_name(user1.clone());
print!("User 1 username: {}", user1.active); // Error - can not use
}
fn change_name(user1: User) {
print!("User 1 username: {:?}", user1.active);
}
Implementing structs
You can also implement structs , which means you can attach functions to instances of
structs
(Very similar to classes in TS)
Copy
struct Rect {
width: u32,
height: u32,
}
impl Rect {
fn area(&self) -> u32 {
self.width * self.height
}
}
fn main() {
let rect = Rect {
width: 30,
height: 50,
};
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 32/43
09/06/2024, 16:00 DailyCode
Enums
Enums in rust are similar to enums in Typescript. They allow you to define a type by
enumerating its possible variants.
Ref - https://doc.rust-lang.org/book/ch06-01-defining-an-enum.html
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 33/43
09/06/2024, 16:00 DailyCode
Copy
enum Direction {
North,
East,
South,
West,
}
fn main() {
let my_direction = Direction::North;
let new_direction = my_direction; // No error, because Direction is
move_around(new_direction);
}
fn move_around(direction: Direction) {
// implements logic to move a character around
}
fn move_around(direction: String) {
if direction == "north" {
println!("Moving North");
}
}
Because we don’t enforce the 4 variants of directions. So this is much looser than strictly
allowing only 4 variants for direction
Enums with values
Copy
// Define an enum called Shape
enum Shape {
Circle(f64), // Variant with associated data (radius)
Square(f64), // Variant with associated data (side length)
Rectangle(f64, f64), // Variant with associated data (width, height
}
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 34/43
09/06/2024, 16:00 DailyCode
fn main() {
// Create instances of different shapes
let circle = Shape::Circle(5.0);
let square = Shape::Square(4.0);
let rectangle = Shape::Rectangle(3.0, 6.0);
Pattern matching
Let you pattern match across various variants of an enum and run some logic
Copy
// Define an enum called Shape
enum Shape {
Circle(f64), // Variant with associated data (radius)
Square(f64), // Variant with associated data (side length)
Rectangle(f64, f64), // Variant with associated data (width, height
}
fn main() {
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 35/43
09/06/2024, 16:00 DailyCode
Error handling
Different languages have different ways to handle errors.
Javascript, for example, has the concept of try catch blocks
Copy
try {
const data = fs.readFileSync('example.txt', 'utf8');
console.log("File content:", data);
} catch (err) {
console.error("Error reading the file:", err);
}
The reason we put the code inside a try catch block is that reading a file is
unpredictable .
The file might not exist, the file might be locked by another process, and hence there is a
possibility of this code throwing an error
The same is true for a rust program trying to access a file. But the way rust does error
handling is slightly different
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 36/43
09/06/2024, 16:00 DailyCode
Result Enum
Copy
enum Result<T, E> {
Ok(T),
Err(E),
}
fn main() {
let greeting_file_result = fs::read_to_string("hello.txt");
}
Complete code
Copy
use std::fs;
fn main() {
let greeting_file_result = fs::read_to_string("hello.txt");
match greeting_file_result {
Ok(file_content) => {
println!("File read successfully: {:?}", file_content);
},
Err(error) => {
println!("Failed to read file: {:?}", error);
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 37/43
09/06/2024, 16:00 DailyCode
}
}
}
Incase you write a function yourself, you can also return a Result from it. As the name
suggests, Result holds the result of a function call that might lead to an error.
Unwraps
Incase you are ok with runtime errors (crashing the process while it runs if an error happens),
then you can unwrap a Result
Copy
use std::fs;
fn main() {
let greeting_file_result = fs::read_to_string("hello.txt");
print!("{}", greeting_file_result.unwrap());
}
fn main() {
let contents = read_file("hello.txt".to_string());
match contents {
Ok(file_content) => {
println!("File content: {}", file_content);
},
Err(error) => {
println!("Error reading file: {:?}", error);
}
}
}
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 38/43
09/06/2024, 16:00 DailyCode
Option enum
Ref - https://viblo.asia/p/billion-dollar-mistake-RQqKLopr57z
The Option enum was introduced in Rust to handle the concept of nullability in a safe and
expressive way. Unlike many programming languages that use a null or similar keyword to
represent the absence of a value, Rust doesn't have null.
Copy
pub enum Option<T> {
None,
Some(T),
}
If you ever have a function that should return null, return an Option instead.
For example
Copy
fn find_first_a(s: String) -> Option<i32> {
for (index, character) in s.chars().enumerate() {
if character == 'a' {
return Some(index as i32);
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 39/43
09/06/2024, 16:00 DailyCode
}
}
return None;
}
fn main() {
let my_string = String::from("raman");
match find_first_a(my_string) {
Some(index) => println!("The letter 'a' is found at index: {}",
None => println!("The letter 'a' is not found in the string."),
}
}
Collections
https://doc.rust-lang.org/book/ch08-00-common-collections.html
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 40/43
09/06/2024, 16:00 DailyCode
fn main() {
let mut rng = thread_rng();
let n: u32 = rng.gen();
println!("Random number: {}", n);
}
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 41/43
09/06/2024, 16:00 DailyCode
fn main() {
// Get the current date and time in UTC
let now = Utc::now();
println!("Current date and time in UTC: {}", now);
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 42/43
Leftovers - Traits, Generics and
09/06/2024, 16:00 DailyCode
https://projects.100xdevs.com/pdf/rust-bootcamp/Rust-Bootcamp-1 43/43