Matt Wang
Denoted as Vec<T>
, only store values of the same type.
// with `Vec::new()` let _v1: Vec<i32> = Vec::new(); // with `Vec::from()` let _v2 = Vec::from([1, 2, 3]); // with vec! macro let _v3 = vec![1, 2, 3]; // init + alloc let _v4 = vec![0; 3]; // equivalent to vec, [0, 0, 0]
// *with capacity specified
let _v2: Vec<i32> = Vec::with_capacity(10);
/* Note that
`Display` trait is behind {}, while
`Debug` is for {:?}
*/
for i in &_v2 {
println!("{}", i); // results in three lines
}
println!("{:?}", _v2); // this gives [1, 2, 3]
{
let v = vec![1, 2, 3, 4];
} // <- v & its elements are freed here
// Need to be mutable for insertion
// Vec<i32> annotation is not needed for `v`
let mut v = Vec::new();
v.push(1); // vec infers the type from data
v.push(2);
// error: expected `i32`, found floating-point number
// v.push(3.1);
// extend from iterator
v.extend([3, 4, 5].iter().copied());
// append v2 to v, v2 become empty
let mut v2 = vec![4, 5, 6];
v.append(&mut v2);
// remove & return the last element, or return None if empty
v.pop();
let v = vec![1, 2, 3, 4, 5];
// method 1: indexing (subscript operator)
let third: &i32 = &v[2];
println!("The third element is {}", third);
// method 2: get() method
let third: Option<&i32> = v.get(2);
match third {
Some(third) => println!("The third element is {}", third),
None => println!("There is no third element."),
}
Choose between indexing and get()
method
based on expected behavior on non-existed index.
let v = vec![1, 2, 3, 4, 5];
// method 1: indexing
let does_not_exist = &v[100]; // panic
// method 2: get() method
let does_not_exist = v.get(100); // None
Ch4: You can’t have mutable and immutable references in the same scope
let mut v = vec![1, 2, 3, 4, 5];
let first = &v[0];
v.push(6);
println!("The first element is: {}", first);
error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable
--> src/main.rs:6:5
|
4 | let first = &v[0];
| - immutable borrow occurs here
5 |
6 | v.push(6);
| ^^^^^^^^^ mutable borrow occurs here
7 |
8 | println!("The first element is: {}", first);
| ----- immutable borrow later used here
enum SpreadsheetCell {
Int(i32),
Float(f64),
Text(String),
}
let row = vec![
SpreadsheetCell::Int(3),
SpreadsheetCell::Text(String::from("blue")),
SpreadsheetCell::Float(10.12),
];
String
is a wrapper over a Vector of 8-bit unsigned int (Vec<u8>
).The term string
in Rust is usually refers to:
String slice: [Ch4] references to some UTF-8 encoded string data
String
type: a growable, mutable, owned, UTF-8 encoded string type
let mut s = String::new();
// method 1
let data = "initial contents"; // string literal
let s = data.to_string(); // based on `Display` trait
// method 2
let s = "initial contents".to_string();
let s = String::from("initial contents");
let mut s = String::from("fo");
s.push('o'); // results in "foo"
s.push_str("bar"); // results in "foobar"
push_str()
does not take ownership.
let mut s1 = String::from("foo");
let s2 = "bar";
s1.push_str(s2);
println!("s2 is {}", s2); // this is valid
let s1 = String::from("tic");
let s2 = String::from("tac");
let s3 = String::from("toe");
method 1: + operator
// note s1 has been moved here and can no longer be used
let s = s1 + "-" + &s2 + "-" + &s3;
println!("{}", s1); // not valid
method 2: format!
macro
// works like `println!`
let s = format!("{}-{}-{}", s1, s2, s3);
println!("{}", s1); // valid
let s1 = String::from("hello");
let h = s1[0]; // raise error
len()
indicates the length in bytes
let hello1 = String::from("Hola"); // 4 char
println!("{}", hello1.len()); // 4 bytes
let hello2 = String::from("Здравствуйте"); // 12 char
println!("{}", hello2.len()); // 24 bytes
-> Index to string does not always correlated the position of bytes
let s = &hello2[0..4];
println!("{}", s); // Зд
let s = &hello2[0..1]; // -> panic
Take a Hindi word as an example:
chars()
& bytes()
for c in "Зд".chars() {
println!("{}", c);
}
/*
З
д
*/
for c in "Зд".bytes() {
println!("{}", c);
}
/*
208
151
208
180
*/
Rust std lib does not support getting grapheme clusters from strings, use crates instead (e.g. unicode-segmentation).
HashMap<K, V>
.Keys or values need to be in the same type.
use std::collections::HashMap;
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);
// each of followings raises error
// scores.insert(10, 50);
// scores.insert(String::from("Yellow"), String::from("50"));
Get value by key with .get()
:
let team_name = String::from("Blue");
let score = scores.get(&team_name).copied().unwrap_or(0);
// `.get(k: &K)` -> Option<&V>
// `.get(k: &K).copied()` -> Option<i32>
// `.get(k: &K).copied().unwrap_or(v: &V)` -> i32
Get value by key with subscript operator:
println!("{}", scores[&team_name]);
let not_exists = String::from("Blues");
println!("{}", scores[¬_exists]); // -> panic!
Iterate over hashmap:
for (key, value) in &scores {
println!("{}: {}", key, value);
}
/*
Yellow: 50
Blue: 10
*/
Print (Debug trait)
println!("{:?}", scores)
// {"Blue": 10, "Yellow": 50}
let key = String::from("Favorite number");
let val = 10;
let mut map = HashMap::new();
Values of types with Copy
trait (e.g. i32
) are copied into map,
while values of those without (e.g. String
) are moved.
map.insert(key, val);
println!("{}", key); // -> raises error
println!("{}", val);
or you can set the reference as key:
map.insert(&key, val);
println!("{}", key); // Favorite number
println!("{}", val); // 10
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
// overwrite
scores.insert(String::from("Blue"), 20);
// insert only when the key is absent
scores.entry(String::from("Blue")).or_insert(50);
where .entry()
returns a enum named Entry
(doc).
println!("{:?}", scores.entry(String::from("Blue")));
// Entry(OccupiedEntry { key: "Blue", value: 10, .. })
println!("{:?}", scores.entry(String::from("Yellow")));
// Entry(VacantEntry("Yellow"))
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);
// {"world": 2, "hello": 1, "wonderful": 1}