In Rust, tendo ad avere problemi di progettazione quando si tratta di scrivere moduli con caratteristiche. Io non sono sempre sicuro se voglio:Quali sono le differenze tra un metodo Trait predefinito e una funzione parametrizzata?
pub trait Foo {
fn foo(&self) -> bool;
fn bar(&self) {
if self.foo() {
// Do something!
} else {
// Do something else!
}
}
}
O
pub trait Foo {
fn foo(&self) -> bool;
}
pub fn bar<T>(fooer: &T) where T: Foo {
if fooer.foo() {
// Do something!
} else {
// Do something else!
}
}
(Naturalmente, esempi reali sono suscettibili di avere tratti più elaborati o firme funzione)
Mentre temi del design sono oltre lo scopo di Stack Overflow, non sono del tutto sicuro di aver compreso le differenze significative e oggettive tra i due, e non ho voglia di sfogliare la libreria standard ha fatto molta luce. È sembra come la libreria standard di Rust preferisce utilizzare variable.method()
in contrasto con mod::function(&variable)
nella maggior parte dei casi. Tuttavia, questo non risponde ancora alla domanda poiché si tratta solo di una guida alla guida allo stile piuttosto che basarsi su una conoscenza oggettiva della differenza.
Oltre all'evidente differenza sintattica, quali sono le principali differenze funzionali tra un metodo di tratto predefinito e una funzione parametrizzata a livello di modulo? Una grande domanda che ho è: il metodo di tratto predefinito monomorfizza per utilizzare la distribuzione statica o lo fa se prende lo self
come se fosse un oggetto tratto?
L'unica differenza che mi viene in mente è che un impl
del tratto può scegliere di ignorare l'implementazione del metodo predefinito, si spera/presumibilmente fornendo un'implementazione che soddisfi lo stesso contratto, mentre sono garantito che l'implementazione mod::function
esegue sempre lo stesso identico codice, indipendentemente da cosa (nel bene o nel male). C'è niente altro? La risposta cambia se sono coinvolti tipi associati o tratti di estensione?