2017-05-22 3 views
0
enum T { 
    A(i32), 
    B(i32), 
    C(i32), 
    D(i32), 
} 

macro_rules! gen_match { 
    ($message:ident, [$(($Variant:ident, $F:ident)),*]) => { 
     match *$message { 
      $($Variant(ref x) => { 
       match *x { 
        Ok(ref a) => { 
         self.$F(a) 
        }, 
        Err(ref err) => return Err(err.clone()) 
       } 
      },)* 
      _ => {} 
     } 
    } 
} 

impl T { 
    fn test(&mut self, message: &T) -> Result<()> { 
     use self::T::*; 

     gen_match!(message, [(A, handle_a), (B, handle_b), (C, handle_c)]); 
     Ok(()) 
    } 
} 

fn main() {} 

マクロ内の自己のメソッドを呼び出す方法は?上記動作しません

Compiling playground v0.0.1 (file:///playground) 
error[E0424]: expected value, found module `self` 
    --> src/main.rs:14:25 
    | 
14 |       self.$F(a) 
    |       ^^^^ `self` value is only available in methods with `self` parameter 
... 
28 |   gen_match!(message, [(A, handle_a), (B, handle_b), (C, handle_c)]); 
    |   ------------------------------------------------------------------- in this macro invocation 

error[E0424]: expected value, found module `self` 
    --> src/main.rs:14:25 
    | 
14 |       self.$F(a) 
    |       ^^^^ `self` value is only available in methods with `self` parameter 
... 
28 |   gen_match!(message, [(A, handle_a), (B, handle_b), (C, handle_c)]); 
    |   ------------------------------------------------------------------- in this macro invocation 

error[E0424]: expected value, found module `self` 
    --> src/main.rs:14:25 
    | 
14 |       self.$F(a) 
    |       ^^^^ `self` value is only available in methods with `self` parameter 
... 
28 |   gen_match!(message, [(A, handle_a), (B, handle_b), (C, handle_c)]); 
    |   ------------------------------------------------------------------- in this macro invocation 

error[E0243]: wrong number of type arguments: expected 2, found 1 
    --> src/main.rs:25:40 
    | 
25 |  fn test(&mut self, message: &T) -> Result<()> { 
    |          ^^^^^^^^^^ expected 2 type arguments 

私は

 match *message { 
      A(ref x) => { 
       match *x { 
        Ok(ref a) => { 
         self.handle_a(a) 
        }, 
        Err(ref err) => return Err(err.clone()) 
       } 
      }, 
      B(ref x) => { 
       match *x { 
        Ok(ref a) => { 
         self.handle_b(a) 
        }, 
        Err(ref err) => return Err(err.clone()) 
       } 
      }, 
      //... 
      _ => {} 
     } 

を生成するためのマクロをしたいと思いますが、それは可能ですか? selfをマクロに渡す必要があります。そうしないと、マクロは解決できません。self

私はrustc 1.19.0を毎晩使用しています。

+1

'gen_match'のみtest''で使用されている場合、あなたは 'macro_rulesを移動することができます'関数の内部で!。 – kennytm

答えて

7

プログラミング上の問題がある場合は、質問者と質問回答者のためにMinimal, Complete, Verifiable Example (MCVE)を生成することが非常に役に立ちます。

たとえば、これはに縮小されている可能性が:

macro_rules! gen_match { 
    ($F:ident) => { 
     self.$F() 
    } 
} 

struct F; 
impl F { 
    fn dummy(&self) {} 
    fn test(&self) { 
     gen_match!(dummy); 
    } 
} 

fn main() {} 

はるかに簡単かつ問題が何であるかを見やすい:それは一致とは何の関係もありません。特殊キーワード/識別子selfを使用するだけです。あなたがマクロにselfに渡すことができ、それを解決するために

、:

macro_rules! gen_match { 
    ($self:ident, $F:ident) => { 
     $self.$F() 
    } 
} 

struct F; 
impl F { 
    fn dummy(&self) {} 
    fn test(&self) { 
     gen_match!(self, dummy); 
    } 
} 
関連する問題