TL;DR

  • マクロは、コードを抽象化する唯一の方法である場合や、関数やジェネリクスではまとめられないボイラープレートに使う。
  • 可読性を保つため、マクロは通常のコードに見た目を近づけるか、まったく違う見た目にする。
  • 構造体のフィールドや enum のバリアントごとにコードを生成するなら derive マクロを使い、先に既存のクレートを探す。

内容

項目28 分別をもってマクロを使おうのうち、マクロを使うときの指針である。

使う場面を絞る

マクロは、コードを抽象化できる唯一の方法である場合に使う。関数やジェネリクスではまとめられないボイラープレートにも使う。

見た目を通常のコードに近づける

可読性を損なわないように、マクロは通常のコードに見た目を近づけるか、まったく違う見た目にする。具体的には、暗黙に参照を挿入するのは避ける。my_macro!(list) より my_macro!(&list) のほうが Rust のコードの書き方に合っている。また、break や return のように、マクロの外に影響する制御フローは使わない(宣言的マクロを利用する上で注意すべきこと)。

型ごとのコード生成には derive マクロを使う

構造体の各フィールドや enum の各バリアントに対してコードを生成するなら、derive マクロを使う。型全体を生成するマクロで書くより、コードが読みやすくなる。

ただし、derive マクロを足すときも、同じ機能のマクロを外部のクレートが提供していないか先に探す。たとえば、整数値を C 風の enum のバリアントに変換するクレートはいくつもある。

#[repr(u8)]
enum Color {
    Red = 0,
    Green = 1,
    Blue = 2,
}

キーワード