<buttonid="sidebar-toggle"class="icon-button"type="button"title="Toggle Table of Contents"aria-label="Toggle Table of Contents"aria-controls="sidebar">
<ahref="print.html"title="Print this book"aria-label="Print this book">
<iid="print-button"class="fa fa-print"></i>
</a>
</div>
</div>
<divid="search-wrapper"class="hidden">
<formid="searchbar-outer"class="searchbar-outer">
<inputtype="search"name="search"id="searchbar"name="searchbar"placeholder="Search this book ..."aria-controls="searchresults-outer"aria-describedby="searchresults-header">
<p>Writing macros can be very complicated. You almost never need to write one, but sometimes you might want to because they are very convenient. Writing macros is interesting because they are almost a different language. To write one, you actually use another macro called <code>macro_rules!</code>. Then you add your macro name and open a <code>{}</code> block. Inside is sort of like a <code>match</code> statement.</p>
<p>Here's one that only takes <code>()</code>, then just returns 6:</p>
<p>But it's not the same as a <code>match</code> statement, because a macro actually doesn't compile anything. It just takes an input and gives an output. Then the compiler checks to see if it makes sense. That's why a macro is like "code that writes code". You will remember that a true <code>match</code> statement needs to give the same type, so this won't work:</p>
<p>This is just fine, and prints <code>You didn't give me 6.</code>. You can also see that it's not a match arm because there's no <code>_</code> case. We can only give it <code>(6)</code>, or <code>()</code>. Anything else will make an error. And the <code>6</code> we give it isn't even an <code>i32</code>, it's just an input 6. You can actually set anything as the input for a macro, because it's just looking at input to see what it gets. For example:</p>
<p>So this strange macro only responds to two things: <code>()</code> and <code>(THis is strange input 하하はは哈哈 but it still works)</code>. Nothing else. It prints:</p>
<pre><codeclass="language-text">You guessed the secret message!
You didn't guess it
</code></pre>
<p>So a macro isn't exactly Rust syntax. But a macro can also understand different types of input that you give it. Take this example:</p>
<p>This will print <code>You gave me: 6</code>. The <code>$input:expr</code> part is important. It means "for an expression, give it the variable name $input". In macros, variables start with a <code>$</code>. In this macro, if you give it one expression, it will print it. Let's try it out some more:</p>
<p>Also note that we wrote <code>{:?}</code>, but it won't check to see if <code>&input</code> implements <code>Debug</code>. It'll just write the code and try to make it compile, and if it doesn't then it gives an error.</p>
<p>So what can a macro see besides <code>expr</code>? They are: <code>block | expr | ident | item | lifetime | literal | meta | pat | path | stmt | tt | ty | vis</code>. This is the complicated part. You can see what each of them means <ahref="https://doc.rust-lang.org/beta/reference/macros-by-example.html">here</a>, where it says:</p>
<pre><codeclass="language-text">item: an Item
block: a BlockExpression
stmt: a Statement without the trailing semicolon (except for item statements that require semicolons)
pat: a Pattern
expr: an Expression
ty: a Type
ident: an IDENTIFIER_OR_KEYWORD
path: a TypePath style path
tt: a TokenTree (a single token or tokens in matching delimiters (), [], or {})
meta: an Attr, the contents of an attribute
lifetime: a LIFETIME_TOKEN
vis: a possibly empty Visibility qualifier
literal: matches -?LiteralExpression
</code></pre>
<p>There is another good site called cheats.rs that explains them <ahref="https://cheats.rs/#macros-attributes">here</a> and gives examples for each.</p>
<p>However, for most macros you will use <code>expr</code>, <code>ident</code>, and <code>tt</code>. <code>ident</code> means identifier and is for variable or function names. <code>tt</code> means token tree and sort of means any type of input. Let's try a simple macro with both.</p>
<p>But it won't print if we give it something with spaces, commas, etc. It will think that we are giving it more than one item or extra information, so it will be confused.</p>
<p>This is where macros start to get difficult.</p>
<p>To give a macro more than one item at a time, we have to use a different syntax. Instead of <code>$input</code>, it will be <code>$($input1),*</code>. This means zero or more (this is what * means), separated by a comma. If you want one or more, use <code>+</code> instead of <code>*</code>.</p>
<p>If we used <code>+</code> instead of <code>*</code> it would give an error, because one time we gave it no input. So <code>*</code> is a bit safer option.</p>
<p>So now we can start to see the power of macros. In this next example we can actually make our own functions:</p>
<p>So now we can start to understand other macros. You can see that some of the macros we've already been using are pretty simple. Here's the one for <code>write!</code> that we used to write to files:</p>
<li>an expression (<code>expr</code>) that gets the variable name <code>$dst</code>.</li>
<li>everything after that. If it wrote <code>$arg:tt</code> then it would only take one, but because it wrote <code>$($arg:tt)*</code> it takes zero, one, or any number.</li>
<p>Then it takes <code>$dst</code> and uses a method called <code>write_fmt</code> on it. Inside that, it uses another macro called <code>format_args!</code> that takes all <code>$($arg)*</code>, or all the arguments we put in.</p>
<p>Now let's take a look at the <code>todo!</code> macro. That's the one you use when you want the program to compile but haven't written your code yet. It looks like this:</p>
<p>This one has two options: you can enter <code>()</code>, or a number of token trees (<code>tt</code>).</p>
<ul>
<li>If you enter <code>()</code>, it just uses <code>panic!</code> with a message. So you could actually just write <code>panic!("not yet implemented")</code> instead of <code>todo!</code> and it would be the same.</li>
<li>If you enter some arguments, it will try to print them. You can see the same <code>format_args!</code> macro inside, which works like <code>println!</code>.</li>
<pre><codeclass="language-text">thread 'main' panicked at 'not yet implemented: Not done yet because of lack of time. Check back in 8 hours', src/main.rs:4:5
</code></pre>
<p>Inside a macro you can even call the same macro. Here's one:</p>
<p>This one takes either <code>()</code>, or one expression, or many expressions. But it ignores all the expressions no matter what you put in, and just calls <code>my_macro!</code> on <code>()</code>. So the output is just <code>Let's print this</code>, four times.</p>
<p>You can see the same thing in the <code>dbg!</code> macro, which also calls itself.</p>
<p>(<code>eprintln!</code> is the same as <code>println!</code> except it prints to <code>io::stderr</code> instead of <code>io::stdout</code>. There is also <code>eprint!</code> that doesn't add a new line)</p>
<p>That matches the first arm, so it will print the file name and line name with the <code>file!</code> and <code>line!</code> macros. It prints <code>[src/main.rs:2]</code>.</p>
<p>This will match the next arm, because it's one expression. It will then call the input <code>tmp</code> and use this code: <code> $crate::eprintln!("[{}:{}] {} = {:#?}", $crate::file!(), $crate::line!(), $crate::stringify!($val), &tmp);</code>. So it will print with <code>file!</code> and <code>line!</code>, then <code>$val</code> made into a <code>String</code>, and pretty print with <code>{:#?}</code> for <code>tmp</code>. So for our input it will write this:</p>
<p>And for the rest of it it just calls <code>dbg!</code> on itself even if you put in an extra comma.</p>
<p>As you can see, macros are very complicated! Usually you only want a macro to automatically do something that a simple function can't do very well. The best way to learn about macros is to look at other macro examples. Not many people can quickly write macros without problems. So don't think that you need to know everything about macros to know how to write in Rust. But if you read other macros, and change them a little, you can easily borrow their power. Then you might start to get comfortable with writing your own.</p>
<p>You saw that we can learn almost anything in Rust just using the Playground. But if you learned everything so far, you will probably want Rust on your computer now. There are always things that you can't do with the Playground like using files or code in more than just one file. Some other things you need Rust on your computer for are input and flags. But most important is that with Rust on your computer you can use crates. We already learned about crates, but in the Playground you could only use the most popular ones. But with Rust on your computer you can use any crate in your program.</p>