Vectors
fn main() {
let a = [1, 2, 3, 4, 5];
let v: Vec<i32> = Vec::new();
}- vector can grow or shrink in size
fn main() {
let a = [1, 2, 3, 4, 5];
let mut v: Vec<i32> = Vec::new();
v.push(6);
v.push(7);
v.push(8);
let v2 = vec![1, 2, 3, 4, 5];
}vec!macro creates a new vector with initial values of the inffered type
use std::vec;
fn main() {
let a = [1, 2, 3, 4, 5];
let mut v: Vec<i32> = Vec::new();
v.push(6);
v.push(7);
v.push(8);
{
let v2 = vec![1, 2, 3, 4, 5];
}
}- Refferecing elements in a vector
fn main() {
let v2 = vec![1, 2, 3, 4, 5];
let third: &i32 = &v2[2];
println!("The third element is {}", third);
}fn main () {
let v2 = vec![1, 2, 3, 4, 5];
let third: &i32 = &v2[20];
println!("The third element is {}", third);
}⛔
Runtime Error:
thread main panicked at 'index out of bounds: the len is 5 but the index is 20'
- vector are stored in the heap, so size of a vector is not known at compile time
- array are stored on the stack, so size of an array is known at compile time
fn main () {
let v2 = vec![1, 2, 3, 4, 5];
let elem: Option<&i32> = v2.get(2);
match elem {
Some(value) => println!("The element is {}", value),
None => println!("There is no element"),
}
}getmethod returnsOption<&T>, which isSome(&element)orNone
fn main() {
let mut v = vec![1, 2, 3, 4, 5];
let elem = &v[2];
v.push(6);
println!("The third element is {}", elem);
}⛔
Error:
cannot borrow v as mutable because it is also borrowed as immutable
- when we use an immutable refference to a vector, we expect to get the orginal vector back, which means that the orginal vector has to be stored somewhere else in memory
- which cannot be done because refferenced to the modified vector
Iterating over the values in a vector
fn main() {
let v = vec![1, 2, 3, 4, 5];
for i in &v {
println!("{}", i);
}
}&vcreates an immutable refference to the vector
fn main() {
let mut v = vec![1, 2, 3, 4, 5];
for i in &mut v {
*i += 50;
}
for i in &v {
print!("{} ", i);
}
}&mut vcreates a mutable refference to the vector*idereferencesito get the value in the vector
$ cargo run
51 52 53 54 55Storing Enums in a Vector
fn main() {
enum SpreadsheetCell {
Int(i32),
Float(f64),
Text(String),
}
let row = vec![
SpreadsheetCell::Int(3),
SpreadsheetCell::Float(10.12),
SpreadsheetCell::Text(String::from("blue")),
];
match &row[0] {
SpreadsheetCell::Int(value) => println!("The value is {}", value),
_ => println!("Not an integer"),
}
}Strings
- Strings are stored as a collection of UTF-8 encoded bytes
- ASCII characters are encoded in 1 byte, while other characters are encoded in 2 bytes
- Unicode scalar values are stored in 4 bytes
- UTF-8 encoding allows for a string to be valid UTF-8, but not valid Unicode, size of a string is not known at compile time
fn main() {
let hello = String::from("السلام عليكم");
let hello = String::from("Dobrý den");
let hello = String::from("Hello");
let hello = String::from("שלום");
let hello = String::from("नमस्ते");
let hello = String::from("こんにちは");
let hello = String::from("안녕하세요");
let hello = String::from("你好");
let hello = String::from("Olá");
let hello = String::from("Здравствуйте");
let hello = String::from("Hola");
}Appending to a String
fn main() {
let mut s = String::from("Hello");
s.push_str(", World");
s.push('!');
println!("{}", s);
}push_strappends a string slice to a stringpushappends a single character to a string
Concatenation with the + Operator
fn main() {
let s1 = String::from("Hello");
let s2 = String::from(", World");
let s3 = s1 + &s2;
println!("{}", s3);
}+operator uses theaddmethod, which takes ownership ofs1and borrowss2fn add(self, s: &str) -> String, takes in an refference to a string slice&strand returns a new string- s3 is the result of the concatenation, so it takes ownership of
s1ands1is no longer valid
Formatting Strings
fn main() {
let s1 = String::from("tic");
let s2 = String::from("tac");
let s3 = String::from("toe");
let s = format!("{}-{}-{}", s1, s2, s3);
println!("{}", s);
}format!macro creates a string without taking ownership of any of its parameters
Indexing into Strings
fn main() {
let s1 = String::from("hello");
let h = s1[0];
}⛔
| let h = s1[0];
| ------------^ string indices are ranges of usize
|
= help: the trait SliceIndex<str> is not implemented for {integer}, which is required by String: Index<_>
use unicode_segmentation::UnicodeSegmentation;
fn main() {
let s1 = String::from("नमस्ते");
for b in s1.bytes() {
print!("{} ", b);
}
for c in s1.chars() {
print!("{} ", c);
}
for g in s1.graphemes(true) {
print!("{} ", g);
}
}
Stringis a wrapper over aVec<u8>, so indexing into a string would return a byte, which is not a character
Bytes
bytes()method returns an iterator over the bytes of a string
[224, 164, 168, 224, 164, 174, 224, 164, 184, 224, 165, 141, 224, 164, 164, 224, 165, 135]
Scalar Values
chars()method returns an iterator over the scalar values of a string
['न', 'म', 'स', '्', 'त', 'े']
Grapheme Clusters
graphemes()in📦 unicode-segmentationcrate method returns an iterator over the grapheme clusters of a string
["न", "म", "स्", "ते"]
⚠️
Using &str[0] is not a good idea because it may not return the expected character
Hash Maps
- A hash map stores a collection of key-value pairs
use std::collections::HashMap;
fn main() {
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);
let team_name = String::from("Blue");
let score = scores.get(&team_name);
match score {
Some(value) => println!("The score is {}", value),
None => println!("There is no score"),
}
}HashMap::new()creates a new hash mapinsert()method inserts a key-value pair into the hash mapget()method returns anOption<&V>whereVis the value type
use std::collections::HashMap;
fn main() {
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Blue"), 50);
//The score is 50
scores.entry(String::from("Yellow")).or_insert(10);
scores.entry(String::from("Yellow")).or_insert(50);
// The score is 10
}entry()method returns anEntryenuminsert()method inserts a value, overwrites the existing valueor_insert()method inserts a value if the key does not exist
use std::collections::HashMap;
fn main() {
let text = "hello world wonderful world";
let mut map = HashMap::new();
for word in text.split_whitespace() {
let count = map.entry(word).or_insert(0);
*count += 1;
}
println!("{:?}", map);
}or_insert()method returns a mutable reference to the value&mut V*count += 1dereferencescountto get the value in the hash map