2013-06-10 11 views
5

Ho una funzione che lavora per realizzare una lista linkata di interi:Rust: utilizzando tratti/typeclasses per implementare una funzione numerica generica

enum List<T> { Cons(T, ~List<T>), End } 

fn range(start: int, end: int) -> ~List<int> { 
    if start >= end { ~End } 
    else { ~Cons(start, range(start+1, end)) } 
} 

Tuttavia, voglio fare una serie di qualsiasi tipo numerico, tra cui indizi, doppi e simili. Ma questo, per esempio, non funziona:

fn range<T: ord>(start: T, end: T) -> ~List<T> { 
    if start >= end { ~End } 
    else { ~Cons(start, range(start+1, end)) } 
} 

che produce:

> rustc list.rs 
list.rs:3:12: 3:15 error: use of undeclared type name `ord` 
list.rs:3 fn range<T: ord>(start: T, end: T) -> ~List<T> { 
         ^~~ 
error: aborting due to previous error 

Come posso fare una generica funzione di ruggine, che si limita ad essere richiamabile dai tipi "numerici"? Senza dover scrivere specificamente l'interfaccia da solo? Avevo dato per scontato che esistessero numerosi tratti di libreria standard (come quelli elencati nella sezione 6.2.1.1 del manuale come eq, ord, ecc., Anche se ora mi chiedo se questi siano proprio "tratti") che Potrei usare quando dichiari le funzioni generiche?

risposta

4

I tratti sono in genere maiuscoli. In questo caso è Ord. Vedi se questo aiuta.

+0

Avrai anche bisogno di un tratto per permetterti di aggiungere numeri. A meno che non sia cambiato dall'ultima volta che l'ho visto, penso che tu voglia il tratto Num. Potrebbe anche essere necessario chiamare da_int per ottenere il valore 1 nel tipo corretto. –

4

Nel master corrente, esiste un carattere denominato "Num" che funge da tratto generale per tutti i tipi numerici. Recentemente è stato fatto un lavoro per unificare molte delle funzioni matematiche comuni per lavorare su questa caratteristica piuttosto che su u8, f32, ecc, in particolare.

Vedere https://github.com/mozilla/rust/blob/master/src/libstd/num/num.rs#L26 per il tratto numerico di cui sopra.

Spero che questo aiuti!