2014-07-21 4 views
5

Trovo questo è particolarmente utile modello per consentire overloading dei metodi:C'è qualche svantaggio nel sovraccaricare le funzioni in ruggine usando un tratto e una funzione generica?

struct Foo { 
    value:uint 
} 

trait HasUIntValue { 
    fn as_uint(self) -> uint; 
} 

impl Foo { 
    fn add<T:HasUIntValue>(&mut self, value:T) { 
    self.value += value.as_uint(); 
    } 
} 

impl HasUIntValue for int { 
    fn as_uint(self) -> uint { 
    return self as uint; 
    } 
} 

impl HasUIntValue for f64 { 
    fn as_uint(self) -> uint { 
    return self as uint; 
    } 
} 

#[test] 
fn test_add_with_int() 
{ 
    let mut x = Foo { value: 10 }; 
    x.add(10i); 
    assert!(x.value == 20); 
} 

#[test] 
fn test_add_with_float() 
{ 
    let mut x = Foo { value: 10 }; 
    x.add(10.0f64); 
    assert!(x.value == 20); 
} 

C'è qualche aspetto negativo significativo per fare questo?

+1

Se la funzione "sovraccarico" deve funzionare su un oggetto che può fare , utilizzare un tratto. In caso contrario, sarebbe meglio eseguire il casting in precedenza o utilizzare più funzioni. – Ryan

+1

Uno può anche diventare più folle: doppia spedizione. guarda come è fatto l'hashing in Rust. – sellibitze

risposta

1

No, non c'è un inconveniente; questo è esattamente il modello per implementare il sovraccarico in Rust.

Nella libreria standard esiste un certo numero di tipi che fanno esattamente questo. Ad esempio, esiste il tratto BytesContainer nel modulo path, che è implementato per vari tipi di stringhe e vettori.

4

C'è almeno uno svantaggio: non può essere un ripensamento.

In C++, l'overloading ad-hoc consente di sovraccaricare una funzione su cui non si ha il controllo (si pensi a terze parti), mentre in Rust questo non è effettivamente fattibile.

Detto questo, ad-hoc sovraccarico è particolarmente utile in C++ a causa di modelli ad hoc, che è l'unico posto dove non si può sapere in anticipo quale funzione la chiamata alla fine di risolvere a. In Rust, dato che i template sono legati da tratti, il fatto che il sovraccarico non può essere un ripensamento non è un problema poiché solo le funzioni dei tratti possono essere chiamate comunque.