Qual è la differenza tra "impl <T> tratto per T dove T: tratto2" e "impl Trait per dyn Trait2"?
Quando si estendono i tratti definiti in altre casse, sembrano esserci due modi per implementare di default un nuovo tratto.
La definizione originale di un tratto è
pub trait Trait1 {
fn f1(&self);
}
Al fine di estendere la funzionalità di questo tratto, definiamo un tratto Trait2,
pub trait Trait2 {
fn f2(&self);
}
Ora, poiché vogliamo che la funzionalità sia disponibile per impostazione predefinita, possiamo implementare quanto segue
impl<T> Trait2 for T
where
T: Trait1,
{
pub fn f2(&self) {
self.f1()
}
}
impl Trait2 for dyn Trait1 {
pub fn f2(&self) {
self.f1()
}
}
Quello che ho osservato è che, quando si mescolano con oggetti tratto, sono necessarie entrambe queste implementazioni.
Capisco che impl<T>quello è per le classi concrete mentre l'altro è per gli dynoggetti. È corretto? C'è un modo per condividere qui l'implementazione predefinita per entrambi questi tipi? Nel mio scenario, ho dovuto copiare e incollare l'intera implementazione con solo la modifica della prima riga.
Risposte
Se ho capito correttamente la tua domanda, aggiungi semplicemente il limite non dimensionato ( ?Sized) a T:
impl<T> Trait2 for T where T: Trait1 + ?Sized
Questo implementa Trait2anche i tipi non dimensionati (ad es. dyn Trait1) Che implementano Trait1. Per impostazione predefinita, tutti i parametri di tipo sono dimensionati e quindi non corrispondono a tipi non dimensionati.
Terreno di gioco