Rust - 集合



Rust 的標準集合庫提供了對最常見通用程式設計資料結構的高效實現。本章討論常用集合的實現——向量 (Vector)、雜湊對映 (HashMap) 和雜湊集合 (HashSet)。

向量 (Vector)

向量是一個可調整大小的陣列。它將值儲存在連續的記憶體塊中。預定義結構 Vec 可用於建立向量。向量的某些重要特性包括:

  • 向量可以在執行時增長或縮小。

  • 向量是同構集合。

  • 向量按特定順序將資料儲存為元素序列。向量中的每個元素都分配了一個唯一的索引號。索引從 0 開始,一直到 n-1,其中 n 是集合的大小。例如,在包含 5 個元素的集合中,第一個元素的索引為 0,最後一個元素的索引為 4。

  • 向量只會在末尾(或附近)追加值。換句話說,向量可以用來實現棧。

  • 向量的記憶體分配在堆上。

語法 - 建立向量

let mut instance_name = Vec::new();

Vec 結構的靜態方法 new() 用於建立向量例項。

或者,也可以使用 vec! 宏建立向量。語法如下:

let vector_name = vec![val1,val2,val3]

下表列出了 Vec 結構的一些常用函式。

序號 方法 簽名和描述
1 new()

pub fn new() -> Vec

構造一個新的空 Vec。除非向其中新增元素,否則向量不會分配記憶體。

2 push()

pub fn push(&mut self, value: T)

將元素追加到集合的末尾。

3 remove()

pub fn remove(&mut self, index: usize) -> T

移除並返回向量中索引位置處的元素,並將之後的所有元素向左移動。

4 contains()

pub fn contains(&self, x: &T) -> bool

如果切片包含具有給定值的元素,則返回 true。

5 len()

pub fn len(&self) -> usize

返回向量中的元素數量,也稱為其“長度”。

示例:使用 new() 建立向量

要建立向量,我們使用靜態方法 new

fn main() {
   let mut v = Vec::new();
   v.push(20);
   v.push(30);
   v.push(40);

   println!("size of vector is :{}",v.len());
   println!("{:?}",v);
}

上面的例子使用在 Vec 結構中定義的靜態方法 new() 建立了一個向量。push(val) 函式將作為引數傳遞的值追加到集合中。len() 函式返回向量的長度。

輸出

size of vector is :3
[20, 30, 40]

示例:使用 vec! 宏建立向量

以下程式碼使用 vec! 宏建立了一個向量。向量的型別由賦給它的第一個值推斷得出。

fn main() {
   let v = vec![1,2,3];
   println!("{:?}",v);
}

輸出

[1, 2, 3]

如前所述,向量只能包含相同資料型別的多個值。以下程式碼片段將引發 error[E0308]: 型別不匹配 錯誤。

fn main() {
   let v = vec![1,2,3,"hello"];
   println!("{:?}",v);
}

示例:push()

將元素追加到集合的末尾。

fn main() {
   let mut v = Vec::new();
   v.push(20);
   v.push(30);
   v.push(40);
   
   println!("{:?}",v);
}

輸出

[20, 30, 40]

示例:remove()

移除並返回向量中索引位置處的元素,並將之後的所有元素向左移動。

fn main() {
   let mut v = vec![10,20,30];
   v.remove(1);
   println!("{:?}",v);
}

輸出

[10, 30]

示例 - contains()

如果切片包含具有給定值的元素,則返回 true:

fn main() {
   let v = vec![10,20,30];
   if v.contains(&10) {
      println!("found 10");
   }
   println!("{:?}",v);
}

輸出

found 10
[10, 20, 30]

示例:len()

返回向量中的元素數量,也稱為其“長度”。

fn main() {
   let v = vec![1,2,3];
   println!("size of vector is :{}",v.len());
}

輸出

size of vector is :3

從向量中訪問值

可以使用相應的索引號訪問向量中的各個元素。以下示例建立了一個向量並列印第一個元素的值。

fn main() {
   let mut v = Vec::new();
   v.push(20);
   v.push(30);

   println!("{:?}",v[0]);
}
Output: `20`

也可以使用對集合的引用來獲取向量中的值。

fn main() {
   let mut v = Vec::new();
   v.push(20);
   v.push(30);
   v.push(40);
   v.push(500);

   for i in &v {
      println!("{}",i);
   }
   println!("{:?}",v);
}

輸出

20
30
40
500
[20, 30, 40, 500]

雜湊對映 (HashMap)

對映是鍵值對(稱為條目)的集合。對映中不能有兩個條目具有相同的鍵。簡而言之,對映是一個查詢表。HashMap 將鍵和值儲存在雜湊表中。條目以任意順序儲存。鍵用於在 HashMap 中搜索值。HashMap 結構在 std::collections 模組中定義。應顯式匯入此模組以訪問 HashMap 結構。

語法:建立 HashMap

let mut instance_name = HashMap::new();

HashMap 結構的靜態方法 new() 用於建立 HashMap 物件。此方法建立一個空的 HashMap。

下面討論 HashMap 的常用函式:

序號 方法 簽名和描述
1 insert()

pub fn insert(&mut self, k: K, v: V) -> Option

插入鍵值對,如果鍵不存在則返回 None。更新後,返回舊值。

2 len()

pub fn len(&self) -> usize

返回對映中的元素數量。

3 get()

pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V> where K: Borrow, Q: Hash + Eq

返回對應於鍵的值的引用。

4 iter()

pub fn iter(&self) -> Iter<'a, K, V>

一個以任意順序訪問所有鍵值對的迭代器。迭代器元素型別為 (&'a K, &'a V)。

5 contains_key

pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool

如果對映包含指定鍵的值,則返回 true。

6 remove()

pub fn remove_entry<Q: ?Sized>(&mut self, k: &Q) -> Option<(K, V)>

從對映中移除一個鍵,如果該鍵以前在對映中,則返回儲存的鍵和值。

示例:insert()

將鍵值對插入到 HashMap 中。

use std::collections::HashMap;
fn main(){
   let mut stateCodes = HashMap::new();
   stateCodes.insert("KL","Kerala");
   stateCodes.insert("MH","Maharashtra");
   println!("{:?}",stateCodes);
}

上面的程式建立了一個 HashMap 並用 2 個鍵值對對其進行初始化。

輸出

{"KL": "Kerala", "MH": "Maharashtra"}

示例:len()

返回對映中的元素數量

use std::collections::HashMap;
fn main() {
   let mut stateCodes = HashMap::new();
   stateCodes.insert("KL","Kerala");
   stateCodes.insert("MH","Maharashtra");
   println!("size of map is {}",stateCodes.len());
}

上面的示例建立了一個 HashMap 並列印其中的元素總數。

輸出

size of map is 2

示例 - get()

返回對應於鍵的值的引用。以下示例檢索 HashMap 中鍵 KL 的值。

use std::collections::HashMap;
fn main() {
   let mut stateCodes = HashMap::new();
   stateCodes.insert("KL","Kerala");
   stateCodes.insert("MH","Maharashtra");
   println!("size of map is {}",stateCodes.len());
   println!("{:?}",stateCodes);

   match stateCodes.get(&"KL") {
      Some(value)=> {
         println!("Value for key KL is {}",value);
      }
      None => {
         println!("nothing found");
      }
   }
}

輸出

size of map is 2
{"KL": "Kerala", "MH": "Maharashtra"}
Value for key KL is Kerala

示例 - iter()

返回一個迭代器,其中包含對所有鍵值對的引用,順序任意。

use std::collections::HashMap;
fn main() {
   let mut stateCodes = HashMap::new();
   stateCodes.insert("KL","Kerala");
   stateCodes.insert("MH","Maharashtra");

   for (key, val) in stateCodes.iter() {
      println!("key: {} val: {}", key, val);
   }
}

輸出

key: MH val: Maharashtra
key: KL val: Kerala

示例:contains_key()

如果對映包含指定鍵的值,則返回 true。

use std::collections::HashMap;
fn main() {
   let mut stateCodes = HashMap::new();
   stateCodes.insert("KL","Kerala");
   stateCodes.insert("MH","Maharashtra");
   stateCodes.insert("GJ","Gujarat");

   if stateCodes.contains_key(&"GJ") {
      println!("found key");
   }
}

輸出

found key

示例:remove()

從對映中移除一個鍵。

use std::collections::HashMap;
fn main() {
   let mut stateCodes = HashMap::new();
   stateCodes.insert("KL","Kerala");
   stateCodes.insert("MH","Maharashtra");
   stateCodes.insert("GJ","Gujarat");

   println!("length of the hashmap {}",stateCodes.len());
   stateCodes.remove(&"GJ");
   println!("length of the hashmap after remove() {}",stateCodes.len());
}

輸出

length of the hashmap 3
length of the hashmap after remove() 2

雜湊集合 (HashSet)

HashSet 是型別 T 的唯一值的集合。新增和刪除值的速度很快,並且快速查詢給定值是否在集合中。

語法:建立 HashSet

let mut hash_set_name = HashSet::new();

HashSet 結構的靜態方法 new 用於建立 HashSet。此方法建立一個空的 HashSet。

下表列出了 HashSet 結構的一些常用方法。

序號 方法 簽名和描述
1 insert()

pub fn insert(&mut self, value: T) -> bool

向集合中新增值。如果集合中不存在此值,則返回 true,否則返回 false。

2 len()

pub fn len(&self) -> usize

返回集合中的元素數量。

3 get()

pub fn get<Q: ?Sized>(&self, value: &Q) -> Option<&T> where T: Borrow, Q: Hash + Eq,

返回集合中與給定值相等的任何值的引用。

4 iter()

pub fn iter(&self) -> Iter<'a, T>

返回一個以任意順序訪問所有元素的迭代器。迭代器元素型別為 &'a T。

5 contains_key

pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool

如果集合包含值,則返回 true。

6 remove()

pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool

從集合中移除值。如果集合中存在該值,則返回 true。

示例 - insert()

向集合中新增值。HashSet 不會向集合中新增重複值。

use std::collections::HashSet;
fn main() {
   let mut names = HashSet::new();

   names.insert("Mohtashim");
   names.insert("Kannan");
   names.insert("TutorialsPoint");
   names.insert("Mohtashim");//duplicates not added

   println!("{:?}",names);
}

輸出

{"TutorialsPoint", "Kannan", "Mohtashim"}

示例:len()

返回集合中的元素數量。

use std::collections::HashSet;
fn main() {
   let mut names = HashSet::new();
   names.insert("Mohtashim");
   names.insert("Kannan");
   names.insert("TutorialsPoint");
   println!("size of the set is {}",names.len());
}

輸出

size of the set is 3

示例 - iter()

返回一個以任意順序訪問所有元素的迭代器。

use std::collections::HashSet;
fn main() {
   let mut names = HashSet::new();
   names.insert("Mohtashim");
   names.insert("Kannan");
   names.insert("TutorialsPoint");
   names.insert("Mohtashim");

   for name in names.iter() {
      println!("{}",name);
   }
}

輸出

TutorialsPoint
Mohtashim
Kannan

示例:get()

返回集合中與給定值相等的任何值的引用。

use std::collections::HashSet;
fn main() {
   let mut names = HashSet::new();
   names.insert("Mohtashim");
   names.insert("Kannan");
   names.insert("TutorialsPoint");
   names.insert("Mohtashim");

   match names.get(&"Mohtashim"){
      Some(value)=>{
         println!("found {}",value);
      }
      None =>{
         println!("not found");
      }
   }
   println!("{:?}",names);
}

輸出

found Mohtashim
{"Kannan", "Mohtashim", "TutorialsPoint"}

示例 - contains()

如果集合包含值,則返回 true。

use std::collections::HashSet;

fn main() {
   let mut names = HashSet::new();
   names.insert("Mohtashim");
   names.insert("Kannan");
   names.insert("TutorialsPoint");

   if names.contains(&"Kannan") {
      println!("found name");
   }  
}

輸出

found name

示例:remove()

從集合中移除值。

use std::collections::HashSet;

fn main() {
   let mut names = HashSet::new();
   names.insert("Mohtashim");
   names.insert("Kannan");
   names.insert("TutorialsPoint");
   println!("length of the Hashset: {}",names.len());
   names.remove(&"Kannan");
   println!("length of the Hashset after remove() : {}",names.len());
}

輸出

length of the Hashset: 3
length of the Hashset after remove() : 2
廣告
© . All rights reserved.