Skip to content

Commit 1681f43

Browse files
committed
Guide: macros
1 parent 655600b commit 1681f43

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed

src/doc/guide.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4711,4 +4711,75 @@ fail.
47114711

47124712
# Macros
47134713

4714+
One of Rust's most advanced features is is system of **macro**s. While
4715+
functions allow you to provide abstractions over values and operations, macros
4716+
allow you to provide abstractions over syntax. Do you wish Rust had the ability
4717+
to do something that it can't currently do? You may be able to write a macro
4718+
to extend Rust's capabilities.
4719+
4720+
You've already used one macro extensively: `println!`. When we invoke
4721+
a Rust macro, we need to use the exclamation mark (`!`). There's two reasons
4722+
that this is true: the first is that it makes it clear when you're using a
4723+
macro. The second is that macros allow for flexible syntax, and so Rust must
4724+
be able to tell where a macro starts and ends. The `!(...)` helps with this.
4725+
4726+
An example of even more advanced macro usage is in Rust's `regex` crate. This
4727+
implements **regular expressions* for Rust. Regular expressions provide a
4728+
powerful way to determine if a string matches a certain pattern, but they also
4729+
have their own syntax. Therefore, they're a perfect fit for Rust's macros.
4730+
4731+
Here's an example of using a regular expression in Rust:
4732+
4733+
```{rust}
4734+
#![feature(phase)]
4735+
#[phase(plugin)]
4736+
extern crate regex_macros;
4737+
extern crate regex;
4738+
4739+
fn main() {
4740+
let re = regex!(r"^\d{4}-\d{2}-\d{2}$");
4741+
println!("Does our expression match? {}", re.is_match("2014-01-01"));
4742+
}
4743+
```
4744+
4745+
This will print "Does our expression match? true". Now, we won't learn
4746+
everything there is to know about regular expressions in this tutorial. We can
4747+
consult [the regex crate's documentation](/regex/index.html) for more on that
4748+
later. For now, here's the important parts:
4749+
4750+
```{rust}
4751+
#![feature(phase)]
4752+
#[phase(plugin)]
4753+
extern crate regex_macros;
4754+
# fn main() {}
4755+
```
4756+
4757+
These attributes allow the `regex_macros` crate to actually hook in to the
4758+
compiler itself and extend it with the regular expression syntax. Macros
4759+
are serious business!
4760+
4761+
Next, let's look at the actual invocation:
4762+
4763+
```{rust}
4764+
# #![feature(phase)]
4765+
# #[phase(plugin)]
4766+
# extern crate regex_macros;
4767+
# extern crate regex;
4768+
# fn main() {
4769+
let re = regex!(r"^\d{4}-\d{2}-\d{2}$");
4770+
# }
4771+
```
4772+
4773+
The `regex!` macro allows us to define a macro. inside of the `()`s, we have a
4774+
`r""` construct. This is a 'raw' string literal, that does no escaping of its
4775+
contents. This is a Rust feature, not a macros feature. Finally, the rest of
4776+
the insides, which is the regular expression itself. This regular expression
4777+
roughly translates to "four digits, followed by a hypen, followed by two
4778+
digits, followed by a hypen, followed by two digits."
4779+
4780+
For more on macros, please consult [the Macros Guide](/guide-macros.html).
4781+
Macros are a very advanced and still slightly experimental feature, and don't
4782+
require a deep understanding to use. The Guide can help you if you want to
4783+
write your own.
4784+
47144785
# Unsafe

0 commit comments

Comments
 (0)