tezvyn:

What are Rust's two macro categories and use cases?

AI-drafted, machine-checkedSource: doc.rust-lang.orgbeginner
WHAT IT TESTS

Whether you know Rust's declarative versus procedural macro distinction.

ANSWER OUTLINE

Name macro_rules! for syntax like vec!, and procedural macros for custom derive on structs.

RED FLAG

Calling them C-style substitution or runtime code.

WHAT THIS TESTS: This question checks if you understand Rust's metaprogramming architecture at a conceptual level. Interviewers want to see that you know macros are not magic but structured compile-time code generation tools. They are probing whether you can distinguish between pattern-based expansion and programmatic token manipulation, and whether you know when to reach for each category.

A GOOD ANSWER COVERS: A strong response names the two categories as declarative and procedural. For declarative macros, explain that they use macro_rules! to match syntax patterns and expand into repetitive boilerplate, with common examples being vec!, println!, or similar helpers. For procedural macros, explain that they accept a stream of tokens, transform an abstract syntax tree, and emit new code, with the most familiar use case being custom derive attributes such as derive(Debug) or derive(Serialize) that auto-implement traits for structs and enums. You should also note that procedural macros run at compile time, not runtime, and must live in their own crate type.

COMMON WRONG ANSWERS: A red flag is describing either macro type as simple text substitution like the C preprocessor; Rust macros operate on tokens and ASTs, not raw strings. Another mistake is saying procedural macros execute at runtime or calling them functions. Some candidates list only derive macros and forget function-like or attribute procedural macros, or they conflate macros with const generics or build scripts. Failing to give a concrete example for each category also weakens the answer significantly.

LIKELY FOLLOW-UPS: An interviewer might ask how macro hygiene works in Rust, or why procedural macros must reside in a separate crate. They could ask you to compare macros to const generics or to explain the difference between function-like procedural macros and declarative macros. You might also be asked about the TokenStream API, debugging macro expansion with cargo expand, or the performance implications of heavy macro use on compile times.

ONE CONCRETE EXAMPLE: Imagine you want a shorthand for initializing a static hash map. A declarative macro using macro_rules! could match key-value pairs and expand them into a series of insert calls wrapped in a block. If instead you want to automatically derive a custom trait like PacketType for every enum in your protocol, you would write a procedural derive macro that reads the enum definition, inspects its variants, and generates an impl PacketType block with a match statement mapping each variant to a discriminant value.

Read the original → doc.rust-lang.org

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.