You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// fn - keyword to declare a function// add - name of the function// (a: i32, b: i32) - function parameters// a, b - variables used inside a function// i32 - 32bit integer type// -> i32 - return typefnadd(a:i32,b:i32) -> i32{
a + b
}
Using a function
fnadd(a:i32,b:i32) -> i32{
a + b
}let x = add(1,1);// 2let y = add(3,0);// 3let z = add(x,1);// 3
Recap
Functions encapsulate functionality
Useful to organize code
Can be executed by "calling" the function
Parameters determine what data a function can work with
Optionally "returns" data
Data sent back from the function
Fundamentals | Println macro
The println macro
Macros expand into additional code
println! "Prints" (displays) information to the terminal
Useful for debugging
let life = 42;println!("hello");// helloprintln!("{:?}", life);// 42println!("{:?} {:?}", life, life);// 42 42println!("the meaning is {:?}", life);// the meaning is 42println!("the meaning is {life:?}");// the meaning is 42println!("{life}");// 42 but visible for end user
Recap
Macros use an exclamation point to call/invoke
Generate additional Rust code
Data can be printed using println!:
{:?}
{varname:?}
{varname}
Fundamentals | Control flow using if
Execution Flow
Code executed line-by-line
Actions are performed & control flow may change
Specific conditions can change control flow
if
else
else if
Example - if..else
let a = 99;if a > 99{println!("Big number");}else{println!("Small number");}
Example - if..else if..else
let a = 99;if a > 200{println!("Huge number");}elseif a > 99{println!("Big number");}else{println!("Small number");}// This will not workif a > 99{println!("Big number");}elseif a > 200{println!("Huge number");}else{println!("Small number");}
Recap
Code executes line-by-line
This can be changed using if
Try to always include else, unless there truly is no alternative case
Fundamentals | Repetition using loops
Repetition
Called "looping" or "iteration"
Multiple types of loops
loop - infinite loop
while - conditional loop
Loop
letmut a = 0;loop{if a == 5{break;}println!("{:?}", a);
a = a + 1;}// > 0// > 1// > 2// > 3// > 4
While loop
letmut a = 0;while a != 5{println!("{:?}", a);
a = a + 1;}// > 0// > 1// > 2// > 3// > 4
Recap
Repetition can be perormed using loops
While loop
Infinite loop
Both types of loops can exit using break
Demo | Basic arithmetic
fnsub(a:i32,b:i32) -> i32{
a - b
}fnmain(){let sum = 2 + 2;let value = 10 - 5;let division = 10 / 2;let mult = 5*5;let five = sub(8,3);let rem = 6 % 3;// 0let rem2 = 6 % 4;// 2}
Rust utilizes an "ownership" model to manage memory
The "owner" of memory is responsible for cleaning up the memory
Memory can either be "moved" or "borrowed"
Example - Move
enumLight{Bright,Dull,}fndisplay_light(light:Light){match light {Light::Bright => println!("bright"),Light::Dull => println!("dull"),}}fnmain(){let dull = Light::Dull;/** * moving into the function. * display_light owns variable dull * and requires to delete data once the function completes */display_light(dull);/** ❌❌❌ * dull variable is deleted and unaccessable. * cant use it no more. */display_light(dull);}
Example - Borrow
enumLight{Bright,Dull,}fndisplay_light(light:&Light){match light {Light::Bright => println!("bright"),Light::Dull => println!("dull"),}}fnmain(){let dull = Light::Dull;/** * letting function to BURROW dull variable using & * main function is still the owner of the dull variable */display_light(&dull);/** ✅✅✅ * dall variable still exists * can use it again */display_light(&dull);}
Recap
Memory must be managed in some way to prevent leaks
Rust uses "ownership" to accomplish memory management
The "owner" of data must clean up the memory
This occurs automatically at the end of the scope
Default behavior is to "move" memory to a new owner
Use an ampersand (&) to allow code to "borrow" memory
Demo | impl
// ~ InterfacestructTemperature{degrees_f:f64,}// ~ ClassimplTemperature{fnfreezing() -> Self{// can also use -> TemperatureSelf{degrees_f:32.0}}fnshow_temp(&self){println!("{:?} degrees F",self.degrees_f);}}fnmain(){let hot = Temperature{degrees_f:99.9};
hot.show_temp();// ~ using as an instantiated entity methodlet freezing = Temperature::freezing();// ~ using as a static method
freezing.show_temp();}
Data Structures | Vector
Vector
Multiple pieces of data
Must be the same type
Used for lists of information
Can add, remove and traverse the entries
Example declaration
let my_numbers = vec![1,2,3];letmut my_numbers = Vec::new();
my_numbers.push(1);
my_numbers.push(2);
my_numbers.push(3);
my_numbers.pop();
my_numbers.len();// this is 2let two = my_numbers[1];
Example iteration
let my_numbers = vec![1,2,3];for num in my_numbers {println!("{:?}", num);}// > 1// > 2// > 3
structEmployee{name:String,// ✅✅✅}fnmain(){let emp_name = "Jayson".to_owned();// OR let emp_name = String::from("Jayson");let emp = Employee{name: emp_name,};}
Recap
String are automatically borrowed
Use .to_owned() or String::from() to create an owned copy of a string slice
Use an owned String when storing in a struct
Demo | Derive
/** * derive - * special macro that applied to enums and structs * and allows you to automatically implement some sort of functionality * in this case we're going to implement printing * * Clone, Copy - informs to compiler that allows it automatically make a copy when storing it to a struct or a function * ownership is no longer transferred when you move enumeration into structure or a function and a cope made instead */#[derive(Debug,Clone,Copy)]enumPosition{Manager,Supervisor,Worker,}#[derive(Debug,Clone,Copy)]structEmployee{position:Position,work_hours:i64,}fnmain(){let me = Employee{position:Position::Worker,mork_hours:40,};match me.position{Position::Manager => println!("manager"),Position::Supervisor => println!("supervisor"),Position::Worker => println!("worker"),}// > worker// with #[derive(Debug)]println!(":?", me.position);// > Worker// with #[derive(Debug)]println!(":?", me);// > Employee { position: Worker, work_hours: 40 }}
Used in scenarious where data may not be required or is unavailable
Unable to find something
Ran out of items in a list
Form field not filled out
Definition
enumOption<T>{Some(T),None}
Example 1
structCustomer{age:Option<i32>,email:String,}let mark = Customer{age:Some(22),email:"[email protected]".to_owned(),};let becky = Customer{age:None,email:"[email protected]".to_owned(),};match becky.age{Some(age) => println!("customer is {:?} years old", age),None => println!("customer age not provided"),}
Example 2 (Function returns None)
structGroceryItem{name:string,qty:i32,}fnfind_quantity(name:&str) -> Option<i32>{let groceries = vec![GroceryItem{ name:"bananas".to_owned(), qty:4,},GroceryItem{ name:"eggs".to_owned(), qty:12,},GroceryItem{ name:"bread".to_owned(), qty:1,},];for item in groceries {if item.name == name {returnSome(item.qty);}}None}
Recap
Option represents either some data or nothing
Some(variable_name)
Data is available
None
No data is available
Useful when needing to work with optional data
Use Option<type> to declare an optional type
Working With Data | Result
Result
A data type that contains one of two typed of data:
"Successful" data
"Error" data
Used in scenarious where an action needs to be taken, but has the possibility of failure
Copying a file
Connection to a website
Definition
enumResult<T,E>{Ok(T),Err(E),}
Example
fnget_sound(name:&string) -> Result<SoundData,String>{if name == "alert"{Ok(SoundData::new("alert"))}else{Err("unable to find sound data".to_owned())}}let sound = get_sound("alert");match sound {Ok(_) => println!("sound data located"),Err(e) => println!("error: {:?}", e),}
Recap
Result represents either success or failure
Ok(variable_name)
The operation was completed
Err(variable_name)
The operation failed
Useful when working with functionaluty that can potentialy fail
for(person, age)in people.iter(){println!("person = {:?}, age = {:?}", person, age);}for person in people.keys(){println!("person = {:?}", person);}for age in people.values(){println!("age = {:?}", age);}
Recap
Store information as key-value pairs
"Key" is used to access the "value"
Very fast to insert & find data using key
Useful when you need to find information and know exactly where it is (via the key)