Menu
Coddy logo textTech

Metodi generici

Fa parte della sezione Programmazione orientata agli oggetti del percorso Rust di Coddy. Lezione 25 di 61.

Una struct generica può contenere qualsiasi tipo, ma non è molto utile senza metodi con cui interagire con i suoi dati. Per definire metodi per una struct generica, è necessaria una sintassi speciale nel blocco impl.

La chiave è dichiarare il parametro generico direttamente nell’impl:

struct Wrapper<T> {
    value: T,
}

impl<T> Wrapper<T> {
    fn get(&self) -> &T {
        &self.value
    }
}

Nota impl<T> prima di Wrapper<T>. Questo indica a Rust che T è un parametro di tipo generico per l'intero blocco di implementazione. Senza questa dichiarazione, Rust cercherebbe un tipo concreto chiamato T e non riuscirebbe a trovarlo.

Il metodo get restituisce &T: un riferimento al tipo contenuto nel wrapper. Funziona sia che T sia un intero, una stringa o qualsiasi altro tipo:

let num_wrapper = Wrapper { value: 100 };
let text_wrapper = Wrapper { value: "Rust" };

println!("{}", num_wrapper.get());  // 100
println!("{}", text_wrapper.get()); // Rust

La stessa definizione del metodo funziona per entrambi, perché il generico T si adatta a ciascun tipo concreto in fase di compilazione.

challenge icon

Sfida

Facile

Estendiamo il tuo contenitore generico con dei metodi! Creerai una struct Box (da non confondere con la Box standard di Rust) che può contenere qualsiasi tipo e fornisce metodi per interagire con il suo contenuto.

Organizzerai il codice in due file:

  • mybox.rs: definisci una struct generica pubblica chiamata MyBox<T> con un campo privato contents di tipo T. Implementa i metodi per questa struct:
    • Una funzione associata new che crea un nuovo MyBox con il valore specificato
    • Un metodo peek che restituisce un riferimento al contenuto (usando &self)
    • Un metodo replace che accetta un nuovo valore e sostituisce il contenuto attuale (usando &mut self)
  • main.rs: importa il tuo modulo e mostra il funzionamento dei metodi generici con tipi diversi. Creerai dei contenitori, darai un'occhiata al loro contenuto e sostituirai i valori per mostrare i metodi in azione.

Ricorda la sintassi chiave per implementare metodi su una struct generica: devi scrivere impl<T> prima di MyBox<T> per indicare a Rust che T è un parametro generico per l'intero blocco di implementazione.

Nel file principale, mostra il funzionamento di MyBox:

  1. Creando un contenitore con un intero (primo input, analizzato come i32)
  2. Dando un'occhiata al suo contenuto e stampando il valore
  3. Sostituendo il contenuto con un nuovo intero (secondo input, analizzato come i32)
  4. Dando di nuovo un'occhiata per mostrare il valore aggiornato
  5. Creando un secondo contenitore con una stringa (terzo input)
  6. Dando un'occhiata al contenuto del contenitore con la stringa

L'output deve seguire questo formato:

Integer box contains: {value}
After replace: {value}
String box contains: {value}

Per esempio, con gli input 10, 25 e Rust:

Integer box contains: 10
After replace: 25
String box contains: Rust

Riceverai tre input: un intero iniziale, un intero sostitutivo e una stringa.

Provalo tu

mod mybox;

use mybox::MyBox;

fn main() {
    // Leggi gli input
    let mut input1 = String::new();
    std::io::stdin().read_line(&mut input1).expect("Failed to read line");
    let initial_int: i32 = input1.trim().parse().expect("Invalid integer");

    let mut input2 = String::new();
    std::io::stdin().read_line(&mut input2).expect("Failed to read line");
    let replacement_int: i32 = input2.trim().parse().expect("Invalid integer");

    let mut input3 = String::new();
    std::io::stdin().read_line(&mut input3).expect("Failed to read line");
    let string_value = input3.trim().to_string();

    // TODO: Crea un MyBox con l'intero iniziale
    
    // TODO: Esamina il suo contenuto e stampa: "Integer box contains: {value}"
    
    // TODO: Sostituisci il contenuto con l'intero sostitutivo
    
    // TODO: Esamina di nuovo il contenuto e stampa: "After replace: {value}"
    
    // TODO: Crea un secondo MyBox con il valore della stringa
    
    // TODO: Esamina il contenuto del box di stringhe e stampa: "String box contains: {value}"
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore Rust online