1. 向量 Vec
Vec 是一個動態陣列,可以在執行時動態增減元素。
fn main() {
let mut v: Vec<i32> = Vec::new();
v.push(10);
v.push(20);
v.push(30);
println!("{:?}", v);
let third = &v[2];
println!("The third element is {}", third);
match v.get(2) {
Some(value) => println!("Got {}", value),
None => println!("No value found"),
}
}
輸出:
[10, 20, 30]
The third element is 30
Got 30
2. 遍歷 Vec
fn main() {
let v = vec![100, 200, 300];
for i in &v {
println!("{}", i);
}
let mut v2 = vec![1, 2, 3];
for i in &mut v2 {
*i += 10;
}
println!("{:?}", v2);
}
輸出:
100
200
300
[11, 12, 13]
3. HashMap 基本用法
HashMap<K, V> 是鍵值對集合。需要引入標準庫的 use std::collections::HashMap;。
use std::collections::HashMap;
fn main() {
let mut scores = HashMap::new();
scores.insert(String::from("Alice"), 50);
scores.insert(String::from("Bob"), 30);
println!("{:?}", scores);
match scores.get("Alice") {
Some(score) => println!("Alice: {}", score),
None => println!("No score for Alice"),
}
}
輸出(HashMap 無順序):
{"Bob": 30, "Alice": 50}
Alice: 50
4. 更新 HashMap
插入時如果 key 已存在,可以選擇覆蓋或保留。
use std::collections::HashMap;
fn main() {
let mut scores = HashMap::new();
scores.insert("Alice", 50);
scores.insert("Bob", 30);
// 覆蓋
scores.insert("Alice", 60);
// 如果不存在才插入
scores.entry("Charlie").or_insert(40);
println!("{:?}", scores);
}
輸出:
{"Bob": 30, "Alice": 60, "Charlie": 40}
5. HashMap 與所有權
插入 HashMap 會轉移所有權:
use std::collections::HashMap;
fn main() {
let key = String::from("name");
let value = String::from("Alice");
let mut map = HashMap::new();
map.insert(key, value);
// println!("{}", key); // key 的所有權已被移動
println!("{:?}", map);
}
輸出:
{"name": "Alice"}
6. 學習心得與補充
今天學到的集合型別中,Vec 很直觀,就像 C++ 的 vector,不過加上了安全性檢查,例如用 get() 時會回傳 Option,這和前幾天學的 Option 剛好呼應。HashMap 也很實用,讓我可以快速管理鍵值對,尤其是 entry().or_insert() 這種用法,感覺比 C++ 的 map 更方便。今天我發現 Rust 的集合型別和之前的所有權規則、Option、Result 都能串連在一起,設計很一致,也讓程式更不容易出錯。另外,HashMap 的輸出順序不固定,這和我以前在 C++ 用 map 的經驗差很多,一開始看起來有點怪,但理解之後覺得很合理,因為它的重點就是查找速度而不是順序。