0Pricing
Learn Rust Coding · Lezione

Vincoli dei trait

Limiti i tipi generici con i trait.

Vincoli dei trait è una lezione Learn Rust Coding gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Learn Rust Coding, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Learn Rust Coding include 4 lezioni in totale.

Funzione dei trait bound

Un trait bound limita un tipo generico ai tipi che implementano un determinato trait. Indica al compilatore quale comportamento il tipo garantisce.

Questo rende disponibili i metodi del trait all'interno del codice generico, mantenendo al contempo la funzione compatibile con molti tipi.

Sintassi dei vincoli inline

La forma più semplice inserisce il vincolo subito dopo il parametro di tipo: T: Trait. Qui T deve implementare Display per poter essere stampato.

All'interno della funzione può ora chiamare qualsiasi metodo fornito da Display.

use std::fmt::Display;

fn show<T: Display>(value: T) {
    println!("value = {}", value);
}

Un trait personalizzato

I vincoli funzionano anche con i trait definiti da Lei. Definisca un trait con un metodo, quindi vincoli una funzione generica a esso.

Questo trait Summary richiede un metodo summarize che restituisca una stringa.

trait Summary {
    fn summarize(&self) -> String;
}

Implementazione e vincoli

Implementi il trait per un tipo; quindi una funzione vincolata potrà accettare qualsiasi tipo che lo implementi. La funzione chiama il metodo del trait senza conoscere il tipo concreto.

Questo programma completo stampa un riepilogo di un Article.

trait Summary { fn summarize(&self) -> String; }

struct Article { title: String }

impl Summary for Article {
    fn summarize(&self) -> String {
        format!("Article: {}", self.title)
    }
}

fn notify<T: Summary>(item: &T) {
    println!("{}", item.summarize());
}

fn main() {
    let a = Article { title: String::from("Rust") };
    notify(&a);
}

Combinazione di vincoli con +

Richieda più trait contemporaneamente unendoli con +. Qui T deve implementare sia Display sia Clone.

La funzione può quindi stampare il valore e anche clonarlo.

use std::fmt::Display;

fn process<T: Display + Clone>(value: T) {
    let copy = value.clone();
    println!("{}", copy);
}

impl Trait negli argomenti

La sintassi impl Trait nella posizione di un argomento è una forma abbreviata per un semplice vincolo. item: &impl Summary equivale a un parametro <T: Summary>.

È concisa nei casi con un solo argomento, ma offre meno controllo quando si riutilizza il tipo.

trait Summary { fn summarize(&self) -> String; }

fn notify(item: &impl Summary) {
    println!("{}", item.summarize());
}

Restituzione di impl Trait

Può anche restituire impl Trait per nascondere un tipo concreto, garantendo al contempo che implementi un trait. È utile per closure e iteratori.

Il chiamante sa soltanto che il risultato implementa il trait indicato.

fn make_adder(n: i32) -> impl Fn(i32) -> i32 {
    move |x| x + n
}

fn main() {
    let add5 = make_adder(5);
    println!("{}", add5(10));
}

I vincoli abilitano gli operatori

Gli operatori corrispondono ai trait: + richiede Add, == richiede PartialEq e i confronti richiedono PartialOrd. Vincolare il tipo a questi trait permette al codice generico di usare gli operatori.

Qui la somma richiede che T implementi Add con se stesso.

use std::ops::Add;

fn sum<T: Add<Output = T>>(a: T, b: T) -> T {
    a + b
}

Metodi predefiniti dei trait

I trait possono fornire implementazioni predefinite dei metodi. Chi li implementa può sovrascriverle oppure usare quelle predefinite. I generics vincolati usano l'implementazione effettiva.

Questo Summary ha un summarize predefinito che i tipi possono mantenere invariato.

trait Summary {
    fn summarize(&self) -> String {
        String::from("(no summary)")
    }
}

struct Note;
impl Summary for Note {}

Dispatch statico e dinamico

I trait bound usano il dispatch statico: il compilatore sceglie il metodo esatto durante la compilazione tramite monomorfizzazione. Al contrario, dyn Trait usa il dispatch dinamico tramite una vtable.

I vincoli sono in genere più veloci; dyn sacrifica velocità in favore di binari più piccoli e della flessibilità a runtime.

Vincoli su struct generiche

I trait bound non sono limitati alle funzioni. Può richiederli quando definisce una struct, così tutte le istanze soddisfano il trait.

Qui ogni Sortable<T> garantisce che i propri elementi possano essere confrontati.

struct Sortable<T: PartialOrd> {
    items: Vec<T>,
}

Verifica rapida

Verifichi la sua comprensione dei trait bound.

Riepilogo

I trait bound vincolano i tipi generici, così il compilatore consente di usare i metodi e gli operatori del trait. Combini i trait con + e usi impl Trait come forma abbreviata negli argomenti o nei valori restituiti.

I vincoli offrono dispatch statico senza overhead, a differenza del dispatch dinamico di dyn Trait.

Domande Frequenti

La lezione «Vincoli dei trait» è gratuita?

Sì — il testo completo di «Vincoli dei trait» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Learn Rust Coding, passa a CoddyKit PRO. Il corso Learn Rust Coding include 4 lezioni in totale.

Cosa imparerò in «Vincoli dei trait»?

Limiti i tipi generici con i trait. Eserciti Learn Rust Coding con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Learn Rust Coding?

Non è richiesta alcuna esperienza precedente. Learn Rust Coding su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.

Quanto tempo richiede la lezione «Vincoli dei trait»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Learn Rust Coding?

Sì. Ogni lezione Learn Rust Coding include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Funzioni generiche
  2. Struct ed enum generici
  3. Vincoli dei trait
  4. Clausole where e vincoli multipli
← Torna a Learn Rust Coding