TL;DR
内容
項目28 分別をもってマクロを使おうのうち、マクロのデメリットの話である。
可読性と保守性の低下
マクロを使うと DSL を作れる。しかし、コードを読んで保守する人は、Rust だけでなく、その DSL もマクロの実装を含めて理解しなければならない。たとえばマクロを使うべきケースの http_codes! は Status という enum を作るが、DSL を見てもそれは分からない。
また、マクロの中のコードは Rust の構文の慣習に従わないので、rustfmt で整形されない。
macro_rules! square {
{ $e:expr } => {
{
let x = $e;
x*x // x * x と整形されない
}
}
}http_codes! では、Informational などの Group のバリアントを、接頭辞の Group:: も use もなしに使っている。これも通常の Rust のコードとは見た目が違う。
コンパイラのエラーメッセージも、どのマクロがどのマクロを呼び出し、どこで問題が起きたのかを、必ずしも詳しく追ってくれない。このときは cargo-expand で展開後のコードを見ると役に立つ。
コードの肥大化
1 行のマクロ呼び出しが、数百行のコードを生成することもある。しかし、呼び出し側からはそれが分からない。そのため、呼び出しが不要になっても削除されずに残り続けやすい。