154 lines
5.3 KiB
Rust
154 lines
5.3 KiB
Rust
// Hey look, we are telling Rust we need to use HashMap from it's standard library
|
|
use std::collections::HashMap;
|
|
|
|
fn number_types() {
|
|
// Let's print the min and max value for each type so you get a feel of when to use them
|
|
println!("i8 MIN {}", std::i8::MIN);
|
|
println!("i8 MAX {}", std::i8::MAX);
|
|
println!("i16 MIN {}", std::i16::MIN);
|
|
println!("i16 MAX {}", std::i16::MAX);
|
|
println!("i32 MIN {}", std::i32::MIN);
|
|
println!("i32 MAX {}", std::i32::MAX);
|
|
println!("i64 MIN {}", std::i64::MIN);
|
|
println!("i64 MAX {}", std::i64::MAX);
|
|
println!("u8 MIN {}", std::u8::MIN);
|
|
println!("u8 MAX {}", std::u8::MAX);
|
|
println!("u16 MIN {}", std::u16::MIN);
|
|
println!("u16 MAX {}", std::u16::MAX);
|
|
println!("u32 MIN {}", std::u32::MIN);
|
|
println!("u32 MAX {}", std::u32::MAX);
|
|
println!("u64 MIN {}", std::u64::MIN);
|
|
println!("u64 MAX {}", std::u64::MAX);
|
|
println!("f32 MIN {}", std::f32::MIN);
|
|
println!("f32 MAX {}", std::f32::MAX);
|
|
println!("f64 MIN {}", std::f64::MIN);
|
|
println!("f64 MAX {}", std::f64::MAX);
|
|
}
|
|
|
|
fn structs_and_hashmaps() {
|
|
// Structs are great for representing data structures
|
|
struct Person {
|
|
name: String,
|
|
age: i16,
|
|
}
|
|
|
|
// Using structs is basically like when defining them, but with values
|
|
let fredrik = Person {
|
|
name: "Fredrik".to_string(),
|
|
age: 33,
|
|
};
|
|
|
|
// Snake case is so much the convention that the compiler will ward you if you try to use camelCase
|
|
let unknown_person = Person {
|
|
name: "Unknown".to_string(),
|
|
age: 0,
|
|
};
|
|
|
|
println!("Hi there {} and {}", fredrik.name, unknown_person.name);
|
|
|
|
// Let's create a HashMap, these work more or less as es6 Sets
|
|
// So when you want to hold arbitrary keys with arbitrary values HashMap is your new best friend
|
|
let mut ages = HashMap::new();
|
|
|
|
// Insert name as key and age as value into the HashMap
|
|
ages.insert(&fredrik.name, &fredrik.age);
|
|
ages.insert(&unknown_person.name, &unknown_person.age);
|
|
|
|
// Print ages to see what we have, notice the {:?} instead of {} here?
|
|
// Complex types need to specify how they should be printed to work with {}
|
|
// {:?} instead makes use of a Debug trait in Rust, that can print
|
|
// almost anything, though not always in a very pretty, readable format
|
|
println!("ages {:?}", ages);
|
|
|
|
// We can also remove stuff
|
|
ages.remove(&unknown_person.name);
|
|
println!("ages {:?}", ages);
|
|
|
|
// And we can also get stuff of course
|
|
if let Some(fredrik_from_the_ages) = ages.get(&fredrik.name) {
|
|
println!("Fredrik's age is {}", fredrik_from_the_ages);
|
|
}
|
|
}
|
|
|
|
fn vectors() {
|
|
// So we first specify the type of values the vector will hold,
|
|
// and then we call new to create an empty vector
|
|
// Also notice the `mut`, without it we can't push or change anything;
|
|
let mut fruits: Vec<String> = Vec::new();
|
|
|
|
// Now we can push stuff to it
|
|
fruits.push("Banana".to_string());
|
|
fruits.push("Banana".to_string());
|
|
fruits.push("Banana".to_string());
|
|
fruits.push("Orange".to_string());
|
|
fruits.push("Orange".to_string());
|
|
|
|
// values can be access by index of course
|
|
println!("{} is a fruit", &fruits[0]);
|
|
|
|
// for in should feel familiar
|
|
for fruit in &fruits {
|
|
println!("{}", fruit);
|
|
}
|
|
|
|
// You can also loop over a range of integers like this
|
|
// This will let us print out the lines of that bad joke you probably saw coming
|
|
// When the fruits vector was populated ;)
|
|
for i in 0..fruits.len() {
|
|
// Match is the switch of Rust, it's smarter as you'll learn later,
|
|
// but this might as well be a switch
|
|
match i {
|
|
// {} creates a block so we can do more than one thing here
|
|
// => will expect one expression
|
|
0 => {
|
|
println!("Knock, knock");
|
|
println!("Who's there?");
|
|
},
|
|
1 => {
|
|
println!("{}. Knock, knock", fruits[i]);
|
|
println!("Who's there?");
|
|
},
|
|
2 => {
|
|
println!("{}. Knock, knock", fruits[i]);
|
|
println!("WHO'S THERE???");
|
|
},
|
|
3 => {
|
|
println!("{}", fruits[i]);
|
|
println!("{}, who?", fruits[i]);
|
|
},
|
|
4 => {
|
|
println!("{} you glad I didn't say {}?", fruits[i], fruits[0]);
|
|
println!("facepalm");
|
|
},
|
|
// Rust wants to make sure your match statement always gets a match to avoid
|
|
// unexpected behaviors, `_` is the "default" or "catch all" rule
|
|
_ => println!("You are not even a fruit"),
|
|
}
|
|
}
|
|
}
|
|
|
|
fn functional_vector_methods() {
|
|
// The `vec!` macro is a shorthand for creating vectors
|
|
let nums = vec![1,2,3,4,5];
|
|
|
|
// We need to specify the type here to make the compiler happy
|
|
let multiplied: &Vec<i32> = &nums
|
|
// Get an iterator from numbs
|
|
.iter()
|
|
// Map over it and multiply each number by 2
|
|
.map(|num| num * 2)
|
|
// Filter out numbers that got too big for our taste
|
|
.filter(|num| *num < 8)
|
|
// collect the results into a new vector
|
|
.collect();
|
|
|
|
println!("Multiplied: {:?}", multiplied);
|
|
}
|
|
|
|
fn main() {
|
|
number_types();
|
|
structs_and_hashmaps();
|
|
vectors();
|
|
functional_vector_methods();
|
|
}
|