Rust - Collezioni

La libreria di raccolta standard di Rust fornisce implementazioni efficienti delle strutture dati di programmazione generiche più comuni. Questo capitolo discute l'implementazione delle raccolte di uso comune: Vector, HashMap e HashSet.

Vettore

Un vettore è un array ridimensionabile. Memorizza i valori in blocchi di memoria contigui. La struttura predefinita Vec può essere utilizzata per creare vettori. Alcune caratteristiche importanti di un vettore sono:

  • Un vettore può crescere o ridursi in fase di esecuzione.

  • Un vettore è una raccolta omogenea.

  • Un vettore memorizza i dati come sequenza di elementi in un ordine particolare. A ogni elemento di un vettore viene assegnato un numero di indice univoco. L'indice inizia da 0 e sale a n-1 dove, n è la dimensione della raccolta. Ad esempio, in una raccolta di 5 elementi, il primo elemento sarà all'indice 0 e l'ultimo elemento all'indice 4.

  • Un vettore aggiungerà valori solo alla (o vicino) alla fine. In altre parole, un vettore può essere utilizzato per implementare uno stack.

  • La memoria per un vettore viene allocata nell'heap.

Sintassi: creazione di un vettore

let mut instance_name = Vec::new();

Il metodo statico new () della struttura Vec viene utilizzato per creare un'istanza vettoriale.

In alternativa, è anche possibile creare un vettore utilizzando il vec! macro. La sintassi è la seguente:

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

La tabella seguente elenca alcune funzioni di uso comune della struttura Vec.

Suor n Metodo Firma e descrizione
1 nuovo()

pub fn new()->Vect

Costruisce un nuovo Vec vuoto. Il vettore non verrà allocato finché gli elementi non verranno inseriti su di esso.

2 Spingere()

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

Aggiunge un elemento al retro di una raccolta.

3 rimuovere()

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

Rimuove e restituisce l'elemento all'indice di posizione all'interno del vettore, spostando tutti gli elementi dopo di esso a sinistra.

4 contiene ()

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

Restituisce vero se la fetta contiene un elemento con il valore dato.

5 len ()

pub fn len(&self) -> usize

Restituisce il numero di elementi nel vettore, denominato anche "lunghezza".

Illustrazione: creazione di un vettore - nuovo ()

Per creare un vettore, usiamo il metodo statico 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);
}

L'esempio precedente crea un vettore utilizzando il metodo statico new () definito nella struttura Vec . La funzione push (val) aggiunge il valore passato come parametro alla raccolta. La funzione len () restituisce la lunghezza del vettore.

Produzione

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

Illustrazione: creazione di un vettore - vec! Macro

Il codice seguente crea un vettore usando il vec! macro. Il tipo di dati del vettore viene dedotto dal primo valore che gli viene assegnato.

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

Produzione

[1, 2, 3]

Come accennato in precedenza, un vettore può contenere solo valori dello stesso tipo di dati. Il seguente frammento di codice genererà un errore [E0308]: errore di tipi non corrispondenti .

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

Illustrazione: push ()

Aggiunge un elemento alla fine di una raccolta.

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

Produzione

[20, 30, 40]

Illustrazione: remove ()

Rimuove e restituisce l'elemento all'indice di posizione all'interno del vettore, spostando tutti gli elementi dopo di esso a sinistra.

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

Produzione

[10, 30]

Illustrazione - contiene ()

Restituisce vero se la fetta contiene un elemento con il valore dato -

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

Produzione

found 10
[10, 20, 30]

Illustrazione: len ()

Restituisce il numero di elementi nel vettore, denominato anche "lunghezza".

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

Produzione

size of vector is :3

Accesso ai valori da un vettore

È possibile accedere ai singoli elementi in un vettore utilizzando i numeri di indice corrispondenti. Il seguente esempio crea un annuncio vettoriale stampa il valore del primo elemento.

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

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

I valori in un vettore possono anche essere recuperati utilizzando il riferimento alla raccolta.

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);
}

Produzione

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

HashMap

Una mappa è una raccolta di coppie chiave-valore (chiamate voci). Due voci in una mappa non possono avere la stessa chiave. In breve, una mappa è una tabella di ricerca. Una HashMap memorizza le chiavi e i valori in una tabella hash. Le voci vengono memorizzate in un ordine arbitrario. La chiave viene utilizzata per cercare i valori nella HashMap. La struttura HashMap è definita nel filestd::collectionsmodulo. Questo modulo dovrebbe essere importato esplicitamente per accedere alla struttura HashMap.

Sintassi: creazione di una mappa hash

let mut instance_name = HashMap::new();

Il metodo statico new () della struttura HashMap viene utilizzato per creare un oggetto HashMap. Questo metodo crea una HashMap vuota.

Le funzioni comunemente usate di HashMap sono discusse di seguito:

Suor n Metodo Firma e descrizione
1 inserire()

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

Inserisce una coppia chiave / valore, se nessuna chiave viene restituita Nessuna. Dopo l'aggiornamento, viene restituito il vecchio valore.

2 len ()

pub fn len(&self) -> usize

Restituisce il numero di elementi nella mappa.

3 ottenere()

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

Restituisce un riferimento al valore corrispondente alla chiave.

4 iter ()

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

Un iteratore che visita tutte le coppie chiave-valore in ordine arbitrario. Il tipo di elemento dell'iteratore è (& 'a K, &' a V).

5 contiene_chiave

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

Restituisce vero se la mappa contiene un valore per la chiave specificata.

6 rimuovere()

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

Rimuove una chiave dalla mappa, restituendo la chiave e il valore memorizzati se la chiave era precedentemente nella mappa.

Illustrazione: insert ()

Inserisce una coppia chiave / valore in HashMap.

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

Il programma precedente crea una HashMap e la inizializza con 2 coppie chiave-valore.

Produzione

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

Illustrazione: len ()

Restituisce il numero di elementi nella mappa

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());
}

L'esempio precedente crea una HashMap e stampa il numero totale di elementi in essa contenuti.

Produzione

size of map is 2

Illustrazione - get ()

Restituisce un riferimento al valore corrispondente alla chiave. L'esempio seguente recupera il valore per la chiave KL in HashMap.

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");
      }
   }
}

Produzione

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

Illustrazione - iter ()

Restituisce un iteratore contenente il riferimento a tutte le coppie chiave-valore in un ordine arbitrario.

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);
   }
}

Produzione

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

Illustrazione: contains_key ()

Restituisce vero se la mappa contiene un valore per la chiave specificata.

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");
   }
}

Produzione

found key

Illustrazione: remove ()

Rimuove una chiave dalla mappa.

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());
}

Produzione

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

HashSet

HashSet è un insieme di valori univoci di tipo T. L'aggiunta e la rimozione di valori è veloce ed è veloce chiedere se un dato valore è nell'insieme o meno. La struttura HashSet è definita nel modulo std :: collections. Questo modulo dovrebbe essere importato esplicitamente per accedere alla struttura HashSet.

Sintassi: creazione di un HashSet

let mut hash_set_name = HashSet::new();

Il metodo statico, nuovo , della struttura HashSet viene utilizzato per creare un HashSet. Questo metodo crea un HashSet vuoto.

La tabella seguente elenca alcuni dei metodi comunemente usati della struttura HashSet.

Suor n Metodo Firma e descrizione
1 inserire()

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

Aggiunge un valore al set. Se l'insieme non aveva questo valore presente, viene restituito true altrimenti false.

2 len ()

pub fn len(&self) -> usize

Restituisce il numero di elementi nell'insieme.

3 ottenere()

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

Restituisce un riferimento al valore nell'insieme, se presente, uguale al valore dato.

4 iter ()

pub fn iter(&self) -> Iter

Restituisce un iteratore che visita tutti gli elementi in ordine arbitrario. Il tipo di elemento dell'iteratore è & 'a T.

5 contiene_chiave

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

Restituisce vero se il set contiene un valore.

6 rimuovere()

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

Rimuove un valore dall'insieme. Restituisce vero se il valore era presente nell'insieme.

Illustrazione - insert ()

Aggiunge un valore al set. Un HashSet non aggiunge valori duplicati alla raccolta.

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);
}

Produzione

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

Illustrazione: len ()

Restituisce il numero di elementi nell'insieme.

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());
}

Produzione

size of the set is 3

Illustrazione - iter ()

Riesegue un iteratore visitando tutti gli elementi in ordine arbitrario.

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);
   }
}

Produzione

TutorialsPoint
Mohtashim
Kannan

Illustrazione: get ()

Restituisce un riferimento al valore dell'insieme, se presente, che è uguale al valore dato.

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);
}

Produzione

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

Illustrazione - contiene ()

Restituisce vero se il set contiene un valore.

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");
   }  
}

Produzione

found name

Illustrazione: remove ()

Rimuove un valore dall'insieme.

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());
}

Produzione

length of the Hashset: 3
length of the Hashset after remove() : 2