2015-08-11 5 views
5

Sto cercando di implementare una macro che implementa il componente aggiuntivo tratto per una struttura, in questo modo:Usando un tipo di argomento macro all'interno di una funzione generata

macro_rules! implement_add { 
    ($t:ty) => { 
     impl std::ops::Add for $t { 
      type Output = $t; 
      fn add(self, rhs: $t) -> $t { 
       $t(self.0 + rhs.0)  // error on this line 
      } 
     } 
    } 
} 

pub struct Length(f64); 

implement_add!(Length); 

fn main() {} 

Tuttavia, questo dà un errore sulla linea indicata:

<anon>:6:17: 6:19 error: unexpected token: `Length` 
<anon>:6     $t(self.0 + rhs.0)  // error on this line 
         ^~ 

Questo non ha senso per me. Tanto più che, se sostituisco $t con Length, compila bene. Sto facendo qualcosa di sbagliato nella mia macro?

Playground: http://is.gd/EIEKub

risposta

4

quando hai inciampato su un po 'sottile, di sistema di tipo di Rust. Length è un tipo, ma Length() è una funzione. Questi esistono in diversi spazi dei nomi.

Un lavoro intorno è quello di estendere la macro per accettare un tipo di e una funzione:

macro_rules! implement_add { 
    ($t:ty, $c:ident) => { 
     impl std::ops::Add for $t { 
      type Output = $t; 
      fn add(self, rhs: $t) -> $t { 
       $c(self.0 + rhs.0)  // error on this line 
      } 
     } 
    } 
} 

pub struct Length(f64); 

implement_add!(Length, Length); 

fn main() {} 
+2

Forse questo, invece, in modo da non dover ripetere l'argomento: http://is.gd/C2imKM –

+0

@BenjaminLindley FWIW, dovresti probabilmente fare 'ret.0 = ret.0 + rhs.0;' invece, poiché '+ =' non è ancora generico, [quindi gli additivi arbitrari non riescono] (http: // is .GD/ApfWLf). – Veedrac