I vettori in Rust

I vettori in Rust sono una collezione di dati dello stesso tipo. Sono molto utili per gestire dati complessi, ad esempio una lista di contatti, una lista di utenti, una raccolta di film, articoli e altro.

Possiamo creare un vettore sia in modo statico (scrivendo vec![1,2,3]) che dinamico (Vec::new()). Possiamo aggiornare facilmente i vettori, aggiungendo e rimuovendo elementi e iterarli per effettuare operazioni.

Esempio dell’uso dei vettori in Rust

Per capire il potenziale dei vettori, creiamo un programma che ci permette di aggiungere i nostri contatti. Ci limiteremo ad implementare una funzione per aggiungere i contatti e un’altra per mostrarli nel terminale. Creiamo un nuovo progetto e in lib.rs aggiungiamo i seguenti moduli: contact, app e ui;

In ui.rs o in ui/mod.rs, creiamo un trait Console con una funzione show. I trait funzionano come un contratto: possono essere implementati nelle nostre strutture in modo da avere già delle funzioni stabilite senza dovere fare tutto manualmente. Nei trait indichiamo soltanto nome, argomenti e tipi di ritorno.

pub trait Console {
    fn show(&self);
}

All’interno del modulo contact inseriamo la struct e le implementazioni per i singoli contatti. Aggiungiamo new, i getter e i setter nell’implementazione principale e poi implementiamo le funzioni del trait Console.

use super::ui::Console;


#[derive(Debug)]
pub struct Contact {
    name: String,
    number: u32,
}

impl Contact {
    pub fn new(name: String, number: u32) -> Self {
        Self { name, number }
    }
    
    //Get e set....

    
    pub fn name(&self) -> &str {
        &self.name
    }
    
    pub fn number(&self) -> u32 {
        self.number
    }
    
    pub fn set_name(&mut self, name: String) {
        self.name = name;
    }
    
    pub fn set_number(&mut self, number: u32) {
        self.number = number;
    }
}

impl Console for Contact {
    fn show(&self) {
        println!("{:#?}",self);
    }
}

Per comodità creiamo un type ContactList. Semplicemente stiamo usando un vettore per i contatti ma gli stiamo dando un nome chiaro. Poi implementiamo le funzioni per aggiungere i contatti e mostrarli.

use super::{contact::Contact, ui::Console};

pub(crate) type ContactList = Vec<Contact>;

pub struct App {
    pub(crate) contact_list: ContactList
}

impl App {
    pub fn new(contact_list: ContactList) -> Self {
        Self { contact_list }
    }

    pub fn add(&mut self,new_contact:Contact) {
        let _ = &self.contact_list.push(new_contact);
    }
}

impl Console for App {
    fn show(&self) {
        for contact in &self.contact_list {
            contact.show();
        }
    }
}

Possiamo scrivere il codice principale in main.rs oppure nella cartella examples fuori da src e con un file con nome a piacere. L’editor creerà i percorsi corretti per usare i moduli in base alla posizione del file. Il programma è disponibile su GitHub/infodit.

fn main() {
    let mut app = App::new(Vec::new());

    app.add(Contact::new(String::from("Marco"), 33872564));

    app.show();
}