►
Description
Ever wondered what the bang ("!") after "println" means? Not anymore! I will show you exactly how macros work, how to use them, and how to write your own macros.
This is the perfect talk for you if you are using macros, but you always wanted to know how they work and how to implement them yourself.
A
A
A
They
start
with
a
hash
and
then
some
name-
and
these
are
c
macros
they're
snippets
replaced
by
the
c
preprocessor
and
they're
nothing
more
than
spring
replacement.
So
you
can't
do
complex,
syntax
matching,
that's
only
possible
with
rus.
They
look
somehow
like
this.
This
is
an
example
we
have
pi
is
3.1415.
A
A
A
A
A
That's
the
second
problem
and,
as
you
can
see
here,
this
is
what
it
what
it
expands
to
it's
one
plus
two
times
two
and
that's,
of
course
wrong,
and
we
can
apply
the
same
fix
as
before,
just
saying
parentheses
around
here,
and
this
works
fine.
This
is
what
it
expands
to
and
rust
solves
all
these
problems.
A
A
A
A
I
look
into
this
file.
This
is
the
entire
macbook
thing.
I
actually
got
that
from
reddit.
I
think
it
was
in
c
plus,
but
I
copied
it
for
c.
It
was
a
bit
hard,
especially
with
these
things
here,
to
correctly
reduce
the
syntax
tree,
but
it
works,
and
I
even
prepared
something
more,
let's
say:
type
script.
A
A
A
A
A
A
A
You
can
have
recursive
macros
that
works,
because
when
calling
they're
already
defined,
you
can
even
define
a
macro
above
this
or
below
this.
You
can
define
a
macro
below
here,
call
it
in
here,
but
it
is
defined
when,
when
this
gets
inserted,
because
we
call
it
below
the
definition
of
this
other
macro-
and
I
have
to
apologize
for
my
title-
it
was
just
it
just
fitted
so
well,
it
should
have
been
syntactically
macro
rules,
the
world.
A
A
A
A
They
can
have
patterns
like
we
saw
before
using
dollar
name
colon
type,
and
this
is
an
example.
It
has
to
be
called
using.
This
is
an
example,
colon
expression,
semicolon
expression
and
every
literal
token
like
in
this
case.
This
is
an
example,
colon
and
semicolon
they
have
to
be
directly
inside.
You
and
patterns
can
be
like
an
expression
or
visibility
or
statement
or
whatever,
and
they
can
have
multiple
tokens
and
they're
correctly
parsed
by
the
compiler.
A
The
problems
are
solved
that
c
macros
have
if
we
change.
If
we
change
the
signature
to
that,
that's
a
bit
simpler
than
before,
and
this
is
the
implementation
you
see,
print
line,
blah
blah
expression
times,
expression
two
and
we
call
it
using
two
plus
expressions:
two
additions:
rust
correctly
groups
them
together.
We
don't
have
the
problem
like
in
c,
where
it's
just
inserted
the
simple
text
replacement,
but
it
groups
it
it
groups
together
correctly
and
the
same
thing
also
applies
for
return
values.
A
Okay,
there
is
more
complex
syntax.
In
macro
headers
we
have
like
a
variable
amount
of
tokens,
so
called
repetition
or
optionals,
and
a
simple
example
is
the
vector
macro.
It
looks
like
this.
We
can
say
dollar
parenthesis,
then
again,
some
list
of
tokens
or
patterns
closing
parenthesis
separator
star
and
inside.
We
can
also
do
it
same
way:
dollar,
open
parenthesis,
content,
close
parenthesis
star.
A
If
we
just
try
to
use
dollar
item
on
its
own.
This
will
not
work
because
it
will
say
variable
still
repeating
at
this
step.
That
will
be
a
compiler
error
and
you
can
actually
use
different
kinds
of
brackets.
When
calling
the
macro,
you
can
use
parenthesis,
you
can
use
brackets
like
in
this
case,
or
you
can
also
use
braces
these
ones.
A
This
is
also
a
very
simple
example
which
says
which
just
prints
all
the
expressions
passed
inside
you
limited
by
calmer
in
this
case
like
you,
can
see
here
and
any
amount
we
can
now
change
this
to
plus,
to
require
at
least
one.
This
will
still
work
perfectly,
but
if
we
don't
specify
anything,
the
compiler
will
say
unexpected
token
in
macro
expansion
or
something
like
that,
I
don't
know
exactly
the
error
message,
but
this
will
not
work.
A
A
A
A
A
Another
problem
that
c
micros
have
is
the
so-called
hygiene,
and
this
is
basically
that
when
we
pass
something
to
the
macro
that
has
the
same
name,
a
variable
that
has
the
same
name
as
something
defined
inside
the
macro,
we
will
overwrite
it
inside
the
macro
and
don't
have
access
to
it
other
later
than,
but
in
rust
we
don't
have
this
problem.
Variables
are
scoped,
and
in
this
case
we
cannot
access
num,
it
will
say,
cannot
find
value
number
in
this
code,
because
the
macro
hygiene
is
defined
outside
of
my
function.
A
We
can
solve
it
by
passing
a
identifier
token,
that's
also
a
different
token
type
and
another
way
to
solve.
It
is
to
define
the
macro
in
the
scope
of
the
variable
like.
If
you
need
a
macro,
only
in
one
function,
you
can
define
it
after
the
variable
has
been
defined
and
then
it
will
correctly
access
the
variable-
and
this
is
the
fixed
example
from
before.
A
Okay
debugging
in
visual
studio
code
is
pretty
weird.
It's
very
inconsistent.
I
tried
some
examples
and
sometimes
it
works.
Sometimes
it
doesn't
really.
It
works
very
well
at
the
call
side.
So
if
you
like
pass
the
statement
inside
the
macro,
then
everything
works
well,
but
it
doesn't
work
always
when
you
try
to
debug
inside
the
macro.
A
A
You
actually
have
to
use
a
attribute
called
macro
export,
because
pub
is
not
supported
on
micros,
and
this
is
an
example.
I
have
a
file
macros.rs,
the
macro,
my
macro,
which
takes
two
to
expressions
and
adds
them
and
prints
them,
and
this
is
the
attribute
called
macro
export,
which
is
added
to
my
macro
and
in
the
main
dot
rs.
A
We
can
say
mod,
macros
and
just
right
after
it,
my
macro
blah
blah.
We
do
not.
We
do
not
have
to
import
it
because
it's
automatically
imported,
if
it's
in
the
same
crate.
If
we
import
something
from
a
different
crate,
you
actually
have
to
add
a
use.
Blah
blah
like
in
lazy
static,
I'm
pretty
sure,
you've
already
seen
laser
static.
If
you
work
with
regex
a
lot,
then
you
say:
use
lazy,
static,
colon
colon
laser
static
and
that
imports
the
macro,
so
you
can
use
it.
A
A
The
argument
list,
which
is
the
same
as
the
macro
call
header
we
saw
before
and
then
the
body
which
gets
inserted-
and
this
is
the
main
file
with
feature
decal
macro
mod
macros
use
macros
my
macro,
and
then
we
can
call
it.
If
we
don't
add
this
line,
it
doesn't
work
because
it's
a
declarative
macro,
a
declared
macro.
A
A
A
A
A
A
A
If
we
run
this
run,
as
you
can
see
here,
it
correctly
outputs
all
these
things,
but
it
doesn't
output
the
identifiers,
it
always
says
a.
We
can
replace
this
with
a
format
arc.
But
what
do
we
put
here
if
we
say
name
we'll
give
an
arrow?
Can
it
find
the
value
a
in
this
code
because
it
tries
to
access
the
variable
a
now?
There
is
a
macro,
that's
built
into
the
rust
compiler,
and
it's
called
ring
by
this,
and
if
you,
if
you
watched
carefully,
then
you
will
see
there
is
something
missing.
A
A
A
A
A
A
A
A
A
Red
and
it
still
works
like
before,
so
how
does
this
macro
work?
Don't
be
scared
of
this?
This
is
normal
things
you
see
when
writing
macros,
but
I
commented
it,
and
this
is
the
first
thing
you
see
these
two
match,
which
is
to
code,
highlights
them,
and
this
says
everything
inside
here
any
amount
of
times
without
a
separator.
If
we
don't
put
anything
before
the
before
the
star
symbol,
it
has
no
separator,
then
we
can
have
any
amount
of
attributes.
A
A
Then
the
name
is
an
identifier,
and
then
these
braces
here,
which
are
these
things,
and
then
we
have
any
amount
of
enum
variants,
separate
by
comma,
with
an
optional
trading
comma.
This
is
what
we've
seen
before
it's
an
optional
comma
after
the
list
of
comma
separated
values
in
here
we
have
attributes
again
for
the
variant
and
then
variant
name.
A
A
It
gives
an
arrow
here,
because
it
would
expect
if
it
sees
a
percent
sign.
It
expects
a
parenthesis,
because
it
knows
it
is
inside
here,
so
this
has
to
exist
this
optional.
So
it
expects
a
parenthesis
after
and
this
parenthesis
is
just
a
list
of
expressions
separated
by
a
comma,
with
an
optional
trailing
comma.
A
Remove
this
again
and
that's
the
entire
macro
header
and
the
implementation
is
not
that
complex.
It's
just
what
we've
seen
before
the
enum
with
all
the
variants-
and
this
is
the
trick,
I'm
using
some
kind
of
pseudo
alternatives
here,
because
rust
will
give
an
error.
If
we
have
both
this
and
this,
it
would
be
valid
for
this
head
to
put
both.
A
A
And
I
have
a
very
interesting
tool
here,
which
is
called
cargo
expand
which
expands
this
macro.
That's
a
tool
you
can
install
using
cargo,
install
expand
cargo,
expand.
I
don't
know
what
the
name
exactly.
I
will
send
it
later
in
the
youtube
chat,
and
if
we
run
this,
we
will
see
exactly
what
it
outputs
this
is.
What
comes
out
is
the
edom.
It's
exactly
what
we
had
before.
I
can
remove
the
hello
variant.
A
A
And
I
talked
about
lazy
static
before
I
have
another
example
for
cargo
expand
here.
This
is
a
very
simple
laser
static
example.
With
static
graph
example.
String
is
hello
world
to
string.
This
does
not
work
when
we
don't
use
laser
static,
because
tostring
is
not
a
constant
method.
You
can
see
here.
If
we
add
const,
this
would
work,
but
it's
not
a
constant
method.