2015-08-11 3 views
5

Я пытаюсь реализовать макрос, который реализует Добавить черта для структуры, как так:Использование макроса аргумент типа внутри сгенерированной функции

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() {} 

Однако это дает ошибку на указанной линии:

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

Это не имеет для меня никакого смысла. Тем более что, если я заменю $t там с Length, он компилируется отлично. Я делаю что-то не так в моем макросе?

площадка: http://is.gd/EIEKub

ответ

4

Вы наткнулись на тонком битой системе типа Руста. Length - тип, но Length() - это функция . Они существуют в разных пространствах имен.

Одна работа вокруг, чтобы расширить свой макрос, чтобы принять тип и функция:

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

сделал это вместо того, чтобы, таким образом, я не должен повторять аргумент: http://is.gd/C2imKM –

+0

@BenjaminLindley FWIW, вы должны, вероятно, сделать 'ret.0 = ret.0 + rhs.0;' вместо этого, так как '+ =' еще не является общим, [поэтому произвольные сбрасываемые данные не выполняются] (http: // is .gd/ApfWLf). – Veedrac

Смежные вопросы