Rust 數據結構:Vector
- Rust 數據結構:Vector
- 創建數組
- 更新數組
- 插入元素
- 刪除元素
- 獲取數組中的元素
- 迭代數組中的值
- 使用枚舉存儲多個類型
- 刪除一個數組會刪除它的元素
Rust 數據結構:Vector
vector 來自標準庫,在內存中連續存儲相同類型的多個值。
創建數組
要創建一個新的空 vector,調用 Vec::new 函數,并指名類型。
let v: Vec<i32> = Vec::new();
Rust 方便地提供了 vec! 宏,它創建具有初始值的Vec<T>,無需類型注釋。
let v = vec![1, 2, 3];
整數類型是 i32,因為這是默認的整數類型,Rust可以推斷出 v 的類型是 Vec<i32>。
更新數組
插入元素
要創建一個 vector 并向其中添加元素,可以使用 push 方法。
let mut v = Vec::new();v.push(5);v.push(6);v.push(7);v.push(8);
與任何變量一樣,如果我們希望能夠改變它的值,我們需要使用 mut 關鍵字使其可變。
我們放在里面的數字都是 i32 類型的,Rust 從數據中推斷出這一點,所以我們不需要 Vec<i32> 注釋。
刪除元素
pop 方法刪除并返回最后一個元素。
獲取數組中的元素
有兩種方法可以引用存儲在 vector 中的值:通過索引或使用 get 方法。
let v = vec![1, 2, 3, 4, 5];let third: &i32 = &v[2];println!("The third element is {third}");let third: Option<&i32> = v.get(2);match third {Some(third) => println!("The third element is {third}"),None => println!("There is no third element."),}
使用 & 和 [] 為我們提供了對索引值處元素的引用。當使用 get 方法將索引作為參數傳遞時,會得到一個 Option<&T>,可以與 match 一起使用。
注意,索引值不能超出現有元素范圍。如果直接訪問超出范圍的元素,程序會報錯。當 get 方法被傳遞給向量之外的索引時,它會返回 None 而不會報錯。
當程序有一個有效的引用時,借閱檢查器執行所有權和借閱規則,以確保這個引用和對vector內容的任何其他引用保持有效。回想一下在同一作用域中不能有可變引用和不可變引用的規則。該規則適用于下面的示例:
let mut v = vec![1, 2, 3, 4, 5];let first = &v[0];v.push(6);println!("The first element is: {first}");
我們保存了一個指向 vector 中第一個元素的不可變引用,并嘗試在末尾添加一個元素。如果我們稍后還試圖在函數中引用該元素,則該程序將無法工作。
為什么對第一個元素的引用要關心 vector 末尾的變化?這個錯誤是由于 vector 的工作方式造成的:因為 vector 將值放在內存中相鄰的位置,如果沒有足夠的空間將 vector 當前存儲的所有元素放在相鄰的位置,則在 vector 的末尾添加新元素可能需要分配新的內存并將舊元素復制到新的空間中。在這種情況下,對第一個元素的引用將指向已釋放的內存。同一作用域中不能有可變引用和不可變引用的規則防止了這種情況。
迭代數組中的值
使用 for 循環可以遍歷所有元素,而不是一次使用索引訪問一個元素。
let v = vec![100, 32, 57];for i in &v {println!("{i}");}
還可以遍歷對可變向量中每個元素的可變引用,以便對所有元素進行修改。
let mut v = vec![100, 32, 57];for i in &mut v {*i += 50;}
要更改可變引用所引用的值,必須先使用 * 解引用操作符獲 取i 中的值,然后才能使用 += 操作符。
由于借用檢查器的規則,對 vector 進行迭代(無論是不可變還是可變)都是安全的。如果試圖在 for 循環體中插入或刪除項,就會報錯。
使用枚舉存儲多個類型
vector 只能存儲相同類型的值。這可能很不方便。我們可以定義一個枚舉,它的變體將保存不同的值類型,所有的枚舉變體將被認為是相同的類型:枚舉的類型。然后,可以創建一個 vector 容器來保存枚舉,從而最終保存不同的類型。
enum SpreadsheetCell {Int(i32),Float(f64),Text(String),}let row = vec![SpreadsheetCell::Int(3),SpreadsheetCell::Text(String::from("blue")),SpreadsheetCell::Float(10.12),];
刪除一個數組會刪除它的元素
當 vector 超出作用域時,它將被釋放。
當 vector 被刪除時,它的所有內容也被刪除,這意味著它保存的整數將被清理。借用檢查器確保僅在 vector 本身有效時才使用對 vector 內容的任何引用。