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