2017-09-06 8 views
1

私はsimplecsに基づいてECSを作っています。エラーは `タプル変形と同じ名前にできません 'という意味ですか?

私はこのようになりますエンティティの構造体を生成するマクロを持っています。

($($name:ident : $component:ty,)*) => { 
     /// A collection of pointers to components 
     #[derive(Clone, Debug, Deserialize, PartialEq)] 
     pub struct Entity { 
      $(
      pub $name: Option<($component)>, 
      )* 
      children: Vec<Entity> 
     } 
} 

実体をシリアル化するためにserdeを使用するための私の目標ですが、どこのコンポーネントがすべきことは、醜いなし値の束を残しましたさあ。だから私はこのようになりますカスタム・シリアライザを実装しようとした:

impl Serialize for Entity { 
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 
     where S: Serializer 
    { 
     let mut num_fields = 0; 
     $(
      match self.$name { 
       Some => num_fields += 1, 
       None => {} 
      }; 
     )* 
      let mut state = serializer.serialize_struct("Entity", num_fields)?; 
      // do serialize 
      state.end() 
    } 
} 

シリアライザはマクロ引数($name)として指定された名前を経由してフィールドにアクセスしようとしますが、私はこれをコンパイルするに行くとき、私はこれを取得しますエラー

error[E0530]: match bindings cannot shadow tuple variants 
    | 
    |   Some => {} 
    |   ^^^^ cannot be named the same as a tuple variant 
+2

あなたは 'Some(pattern)'の代わりに 'Some'を使用しています。内容を気にしない場合は、一致を使う代わりにif条件で 'self。$ name.is_some()'を使います。 –

答えて

3

構文self.$nameは、メンバー変数にアクセスするのが正しいです。 @ oli_obk-kerさんの質問によると、エラーはSome(pattern)の代わりにSomeを使用しているためです。

  match self.$name { 
      Some(_) => num_fields += 1, 
//    ^~~ 
      None => {} 
     }; 
// 
// even better, use `if self.$name.is_some() { num_fields += 1; }`. 

しかし、あなた自身でもserializeを書く必要はありません。フィールドに#[serde(skip_serializing_if = "f") attributeを使用すると、f(&self.field)がtrueを返した場合に、生成されたコードが書き出すことを避けることができます。

($($name:ident : $component:ty,)*) => { 
    /// A collection of pointers to components 
    #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 
    pub struct Entity { 
     $(
      #[serde(skip_serializing_if = "Option::is_none")] // <-- add this 
      pub $name: Option<($component)>, 
     )* 
     children: Vec<Entity> 
    } 
} 
関連する問題