Menu
Coddy logo textTech

Struct generiche

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

Finora, ogni struct che hai creato aveva campi con tipi specifici e concreti. Un Pet ha un nome di tipo String, un Rectangle ha dimensioni di tipo f64. Ma cosa succede se vuoi creare una struct che possa contenere qualsiasi tipo di dato?

È qui che entrano in gioco i generici. I generici ti permettono di scrivere codice flessibile e riutilizzabile che funziona con più tipi. Invece di codificare un tipo specifico, usi un segnaposto, in genere T, che viene sostituito con un tipo concreto quando usi la struct.

Ecco una semplice struct wrapper che può contenere qualsiasi tipo:

struct Wrapper<T> {
    value: T,
}

<T> dopo il nome della struct dichiara un parametro di tipo generico. All'interno della struct, T funge da segnaposto per il tipo che userai effettivamente. Quando crei un'istanza, Rust deduce il tipo concreto:

let int_wrapper = Wrapper { value: 42 };        // T è i32
let float_wrapper = Wrapper { value: 3.14 };    // T è f64
let text_wrapper = Wrapper { value: "hello" };  // T è &str

Ognuno di questi è un tipo concreto diverso, Wrapper<i32>, Wrapper<f64> e Wrapper<&str>, ma condividono tutti la stessa definizione di struct. Questo elimina la necessità di scrivere struct separate IntWrapper, FloatWrapper e StringWrapper che fanno essenzialmente la stessa cosa.

La lettera T è solo una convenzione (abbreviazione di "Type"). Potresti usare qualsiasi identificatore valido, ma T è lo standard in Rust e nella maggior parte degli altri linguaggi con i generici.

challenge icon

Sfida

Facile

Costruiamo un contenitore generico in grado di contenere qualsiasi tipo di valore! Creerai una struct Container che dimostra come i generics rendano il tuo codice flessibile e riutilizzabile.

Organizzerai il codice in due file:

  • container.rs: definisci una struct generica pubblica chiamata Container<T> con un unico campo pubblico item di tipo T. Questo contenitore deve poter contenere qualsiasi tipo: interi, numeri in virgola mobile, stringhe o qualsiasi altra cosa.
  • main.rs: importa il modulo del contenitore e dimostrane la flessibilità creando contenitori che contengono diversi tipi di dati. Creerai tre contenitori e mostrerai cosa contiene ciascuno.

Nel file principale, crea i seguenti contenitori:

  1. Un contenitore che contiene un valore intero (il primo input, analizzato come i32)
  2. Un contenitore che contiene un valore in virgola mobile (il secondo input, analizzato come f64)
  3. Un contenitore che contiene una stringa (il terzo input, mantenuto come String)

L'output deve mostrare il contenuto di ciascun contenitore in questo formato:

Integer container: {value}
Float container: {value}
String container: {value}

Per esempio, con gli input 42, 3.14 e hello:

Integer container: 42
Float container: 3.14
String container: hello

Nota come la stessa definizione di Container<T> funzioni per tutti e tre i diversi tipi: questa è la potenza dei generics!

Riceverai tre input: un valore intero, un valore in virgola mobile e una stringa.

Provalo tu

mod container;

use container::Container;

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

    let mut input2 = String::new();
    std::io::stdin().read_line(&mut input2).expect("Failed to read line");
    let float_value: f64 = input2.trim().parse().expect("Failed to parse float");

    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 tre contenitori usando Container<T>
    // 1. Un contenitore di interi che contiene int_value
    // 2. Un contenitore di numeri in virgola mobile che contiene float_value
    // 3. Un contenitore di stringhe che contiene string_value

    // TODO: Stampa il contenuto di ciascun contenitore nel formato richiesto
    // Integer container: {value}
    // Float container: {value}
    // String container: {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