% Associated Types
-Associated types are a powerful part of Rust's type system. They're related to
-the idea of a 'type family', in other words, grouping multiple types together. That
-description is a bit abstract, so let's dive right into an example. If you want
+Associated types are a powerful part of Rust’s type system. They’re related to
+the idea of a ‘type family’, in other words, grouping multiple types together. That
+description is a bit abstract, so let’s dive right into an example. If you want
to write a `Graph` trait, you have two types to be generic over: the node type
and the edge type. So you might write a trait, `Graph<N, E>`, that looks like
this:
No need to deal with the `E`dge type here!
-Let's go over all this in more detail.
+Let’s go over all this in more detail.
## Defining associated types
-Let's build that `Graph` trait. Here's the definition:
+Let’s build that `Graph` trait. Here’s the definition:
```rust
trait Graph {
## Implementing associated types
Just like any trait, traits that use associated types use the `impl` keyword to
-provide implementations. Here's a simple implementation of Graph:
+provide implementations. Here’s a simple implementation of Graph:
```rust
# trait Graph {
This silly implementation always returns `true` and an empty `Vec<Edge>`, but it
gives you an idea of how to implement this kind of thing. We first need three
`struct`s, one for the graph, one for the node, and one for the edge. If it made
-more sense to use a different type, that would work as well, we're just going to
+more sense to use a different type, that would work as well, we’re just going to
use `struct`s for all three here.
Next is the `impl` line, which is just like implementing any other trait.
From here, we use `=` to define our associated types. The name the trait uses
-goes on the left of the `=`, and the concrete type we're `impl`ementing this
+goes on the left of the `=`, and the concrete type we’re `impl`ementing this
for goes on the right. Finally, we use the concrete types in our function
declarations.
% Closures
Rust not only has named functions, but anonymous functions as well. Anonymous
-functions that have an associated environment are called 'closures', because they
+functions that have an associated environment are called ‘closures’, because they
close over an environment. Rust has a really great implementation of them, as
-we'll see.
+we’ll see.
# Syntax
assert_eq!(2, plus_one(1));
```
-We create a binding, `plus_one`, and assign it to a closure. The closure's
+We create a binding, `plus_one`, and assign it to a closure. The closure’s
arguments go between the pipes (`|`), and the body is an expression, in this
case, `x + 1`. Remember that `{ }` is an expression, so we can have multi-line
closures too:
assert_eq!(4, plus_two(2));
```
-You'll notice a few things about closures that are a bit different than regular
+You’ll notice a few things about closures that are a bit different than regular
functions defined with `fn`. The first of which is that we did not need to
annotate the types of arguments the closure takes or the values it returns. We
can:
assert_eq!(2, plus_one(1));
```
-But we don't have to. Why is this? Basically, it was chosen for ergonomic reasons.
+But we don’t have to. Why is this? Basically, it was chosen for ergonomic reasons.
While specifying the full type for named functions is helpful with things like
documentation and type inference, the types of closures are rarely documented
since they’re anonymous, and they don’t cause the kinds of error-at-a-distance
that inferring named function types can.
-The second is that the syntax is similar, but a bit different. I've added spaces
+The second is that the syntax is similar, but a bit different. I’ve added spaces
here to make them look a little closer:
```rust
let plus_one_v3 = |x: i32 | x + 1 ;
```
-Small differences, but they're similar in ways.
+Small differences, but they’re similar in ways.
# Closures and their environment
-Closures are called such because they 'close over their environment.' It
+Closures are called such because they ‘close over their environment’. It
looks like this:
```rust
^
```
-A verbose yet helpful error message! As it says, we can't take a mutable borrow
+A verbose yet helpful error message! As it says, we can’t take a mutable borrow
on `num` because the closure is already borrowing it. If we let the closure go
out of scope, we can:
```
`Vec<T>` has ownership over its contents, and therefore, when we refer to it
-in our closure, we have to take ownership of `nums`. It's the same as if we'd
+in our closure, we have to take ownership of `nums`. It’s the same as if we’d
passed `nums` to a function that took ownership of it.
## `move` closures
Now, even though the keyword is `move`, the variables follow normal move semantics.
In this case, `5` implements `Copy`, and so `owns_num` takes ownership of a copy
-of `num`. So what's the difference?
+of `num`. So what’s the difference?
```rust
let mut num = 5;
```
So in this case, our closure took a mutable reference to `num`, and then when
-we called `add_num`, it mutated the underlying value, as we'd expect. We also
+we called `add_num`, it mutated the underlying value, as we’d expect. We also
needed to declare `add_num` as `mut` too, because we’re mutating its
environment.
-If we change to a `move` closure, it's different:
+If we change to a `move` closure, it’s different:
```rust
let mut num = 5;
# Closure implementation
-Rust's implementation of closures is a bit different than other languages. They
-are effectively syntax sugar for traits. You'll want to make sure to have read
+Rust’s implementation of closures is a bit different than other languages. They
+are effectively syntax sugar for traits. You’ll want to make sure to have read
the [traits chapter][traits] before this one, as well as the chapter on [trait
objects][trait-objects].
# }
```
-You'll notice a few differences between these traits, but a big one is `self`:
+You’ll notice a few differences between these traits, but a big one is `self`:
`Fn` takes `&self`, `FnMut` takes `&mut self`, and `FnOnce` takes `self`. This
-covers all three kinds of `self` via the usual method call syntax. But we've
+covers all three kinds of `self` via the usual method call syntax. But we’ve
split them up into three traits, rather than having a single one. This gives us
a large amount of control over what kind of closures we can take.
return closures: just like any other trait!
This also means that we can choose static vs dynamic dispatch as well. First,
-let's write a function which takes something callable, calls it, and returns
+let’s write a function which takes something callable, calls it, and returns
the result:
```rust
We pass our closure, `|x| x + 2`, to `call_with_one`. It just does what it
suggests: it calls the closure, giving it `1` as an argument.
-Let's examine the signature of `call_with_one` in more depth:
+Let’s examine the signature of `call_with_one` in more depth:
```rust
fn call_with_one<F>(some_closure: F) -> i32
```
We take one parameter, and it has the type `F`. We also return a `i32`. This part
-isn't interesting. The next part is:
+isn’t interesting. The next part is:
```rust
# fn call_with_one<F>(some_closure: F) -> i32
takes a `i32` as an argument and returns an `i32`, and so the generic bound we use
is `Fn(i32) -> i32`.
-There's one other key point here: because we're bounding a generic with a
-trait, this will get monomorphized, and therefore, we'll be doing static
-dispatch into the closure. That's pretty neat. In many langauges, closures are
+There’s one other key point here: because we’re bounding a generic with a
+trait, this will get monomorphized, and therefore, we’ll be doing static
+dispatch into the closure. That’s pretty neat. In many langauges, closures are
inherently heap allocated, and will always involve dynamic dispatch. In Rust,
we can stack allocate our closure environment, and statically dispatch the
call. This happens quite often with iterators and their adapters, which often
It’s very common for functional-style code to return closures in various
situations. If you try to return a closure, you may run into an error. At
-first, it may seem strange, but we'll figure it out. Here's how you'd probably
+first, it may seem strange, but we’ll figure it out. Here’s how you’d probably
try to return a closure from a function:
```rust,ignore
size the return type is. But since `Fn` is a trait, it could be various
things of various sizes: many different types can implement `Fn`. An easy
way to give something a size is to take a reference to it, as references
-have a known size. So we'd write this:
+have a known size. So we’d write this:
```rust,ignore
fn factory() -> &(Fn(i32) -> Vec<i32>) {
```
Right. Because we have a reference, we need to give it a lifetime. But
-our `factory()` function takes no arguments, so elision doesn't kick in
+our `factory()` function takes no arguments, so elision doesn’t kick in
here. What lifetime can we choose? `'static`:
```rust,ignore
```
-This error is letting us know that we don't have a `&'static Fn(i32) -> i32`,
+This error is letting us know that we don’t have a `&'static Fn(i32) -> i32`,
we have a `[closure <anon>:7:9: 7:20]`. Wait, what?
Because each closure generates its own environment `struct` and implementation
this closure. So Rust shows them as `closure <anon>`, rather than some
autogenerated name.
-But why doesn't our closure implement `&'static Fn`? Well, as we discussed before,
+But why doesn’t our closure implement `&'static Fn`? Well, as we discussed before,
closures borrow their environment. And in this case, our environment is based
on a stack-allocated `5`, the `num` variable binding. So the borrow has a lifetime
of the stack frame. So if we returned this closure, the function call would be
# }
```
-We use a trait object, by `Box`ing up the `Fn`. There's just one last problem:
+We use a trait object, by `Box`ing up the `Fn`. There’s just one last problem:
```text
error: `num` does not live long enough
```
By making the inner closure a `move Fn`, we create a new stack frame for our
-closure. By `Box`ing it up, we've given it a known size, and allowing it to
+closure. By `Box`ing it up, we’ve given it a known size, and allowing it to
escape our stack frame.
% Crates and Modules
-When a project starts getting large, it's considered good software
+When a project starts getting large, it’s considered good software
engineering practice to split it up into a bunch of smaller pieces, and then
-fit them together. It's also important to have a well-defined interface, so
+fit them together. It’s also important to have a well-defined interface, so
that some of your functionality is private, and some is public. To facilitate
these kinds of things, Rust has a module system.
# Basic terminology: Crates and Modules
-Rust has two distinct terms that relate to the module system: *crate* and
-*module*. A crate is synonymous with a *library* or *package* in other
-languages. Hence "Cargo" as the name of Rust's package management tool: you
+Rust has two distinct terms that relate to the module system: ‘crate’ and
+‘module’. A crate is synonymous with a ‘library’ or ‘package’ in other
+languages. Hence “Cargo” as the name of Rust’s package management tool: you
ship your crates to others with Cargo. Crates can produce an executable or a
library, depending on the project.
You can then define a tree of sub-modules under that root module. Modules allow
you to partition your code within the crate itself.
-As an example, let's make a *phrases* crate, which will give us various phrases
-in different languages. To keep things simple, we'll stick to "greetings" and
-"farewells" as two kinds of phrases, and use English and Japanese (日本語) as
-two languages for those phrases to be in. We'll use this module layout:
+As an example, let’s make a *phrases* crate, which will give us various phrases
+in different languages. To keep things simple, we’ll stick to ‘greetings’ and
+‘farewells’ as two kinds of phrases, and use English and Japanese (日本語) as
+two languages for those phrases to be in. We’ll use this module layout:
```text
+-----------+
modules. You can see that they form a tree, branching out from the crate
*root*, which is the root of the tree: `phrases` itself.
-Now that we have a plan, let's define these modules in code. To start,
+Now that we have a plan, let’s define these modules in code. To start,
generate a new crate with Cargo:
```bash
# Defining Modules
-To define each of our modules, we use the `mod` keyword. Let's make our
+To define each of our modules, we use the `mod` keyword. Let’s make our
`src/lib.rs` look like this:
```
with double-colon (`::`) notation: our four nested modules are
`english::greetings`, `english::farewells`, `japanese::greetings`, and
`japanese::farewells`. Because these sub-modules are namespaced under their
-parent module, the names don't conflict: `english::greetings` and
+parent module, the names don’t conflict: `english::greetings` and
`japanese::greetings` are distinct, even though their names are both
`greetings`.
```
`libphrase-hash.rlib` is the compiled crate. Before we see how to use this
-crate from another crate, let's break it up into multiple files.
+crate from another crate, let’s break it up into multiple files.
# Multiple file crates
-If each crate were just one file, these files would get very large. It's often
+If each crate were just one file, these files would get very large. It’s often
easier to split up crates into multiple files, and Rust supports this in two
ways.
If we do that, Rust will expect to find either a `english.rs` file, or a
`english/mod.rs` file with the contents of our module.
-Note that in these files, you don't need to re-declare the module: that's
+Note that in these files, you don’t need to re-declare the module: that’s
already been done with the initial `mod` declaration.
Using these two techniques, we can break up our crate into two directories and
These two declarations tell Rust to look for either `src/english.rs` and
`src/japanese.rs`, or `src/english/mod.rs` and `src/japanese/mod.rs`, depending
-on our preference. In this case, because our modules have sub-modules, we've
+on our preference. In this case, because our modules have sub-modules, we’ve
chosen the second. Both `src/english/mod.rs` and `src/japanese/mod.rs` look
like this:
Again, these declarations tell Rust to look for either
`src/english/greetings.rs` and `src/japanese/greetings.rs` or
`src/english/farewells/mod.rs` and `src/japanese/farewells/mod.rs`. Because
-these sub-modules don't have their own sub-modules, we've chosen to make them
+these sub-modules don’t have their own sub-modules, we’ve chosen to make them
`src/english/greetings.rs` and `src/japanese/farewells.rs`. Whew!
The contents of `src/english/greetings.rs` and `src/japanese/farewells.rs` are
-both empty at the moment. Let's add some functions.
+both empty at the moment. Let’s add some functions.
Put this in `src/english/greetings.rs`:
```
Of course, you can copy and paste this from this web page, or just type
-something else. It's not important that you actually put "konnichiwa" to learn
+something else. It’s not important that you actually put ‘konnichiwa’ to learn
about the module system.
Put this in `src/japanese/farewells.rs`:
}
```
-(This is "Sayōnara", if you're curious.)
+(This is ‘Sayōnara’, if you’re curious.)
-Now that we have some functionality in our crate, let's try to use it from
+Now that we have some functionality in our crate, let’s try to use it from
another crate.
# Importing External Crates
-We have a library crate. Let's make an executable crate that imports and uses
+We have a library crate. Let’s make an executable crate that imports and uses
our library.
-Make a `src/main.rs` and put this in it (it won't quite compile yet):
+Make a `src/main.rs` and put this in it (it won’t quite compile yet):
```rust,ignore
extern crate phrases;
```
The `extern crate` declaration tells Rust that we need to compile and link to
-the `phrases` crate. We can then use `phrases`' modules in this one. As we
+the `phrases` crate. We can then use `phrases`’ modules in this one. As we
mentioned earlier, you can use double colons to refer to sub-modules and the
functions inside of them.
rather than a library crate. Our package now has two crates: `src/lib.rs` and
`src/main.rs`. This pattern is quite common for executable crates: most
functionality is in a library crate, and the executable crate uses that
-library. This way, other programs can also use the library crate, and it's also
+library. This way, other programs can also use the library crate, and it’s also
a nice separation of concerns.
-This doesn't quite work yet, though. We get four errors that look similar to
+This doesn’t quite work yet, though. We get four errors that look similar to
this:
```bash
phrases/src/main.rs:4:5: 4:76 note: expansion site
```
-By default, everything is private in Rust. Let's talk about this in some more
+By default, everything is private in Rust. Let’s talk about this in some more
depth.
# Exporting a Public Interface
Rust allows you to precisely control which aspects of your interface are
public, and so private is the default. To make things public, you use the `pub`
-keyword. Let's focus on the `english` module first, so let's reduce our `src/main.rs`
+keyword. Let’s focus on the `english` module first, so let’s reduce our `src/main.rs`
to just this:
```{rust,ignore}
}
```
-In our `src/lib.rs`, let's add `pub` to the `english` module declaration:
+In our `src/lib.rs`, let’s add `pub` to the `english` module declaration:
```{rust,ignore}
pub mod english;
mod japanese;
```
-And in our `src/english/mod.rs`, let's make both `pub`:
+And in our `src/english/mod.rs`, let’s make both `pub`:
```{rust,ignore}
pub mod greetings;
pub mod farewells;
```
-In our `src/english/greetings.rs`, let's add `pub` to our `fn` declaration:
+In our `src/english/greetings.rs`, let’s add `pub` to our `fn` declaration:
```{rust,ignore}
pub fn hello() -> String {
Now that our functions are public, we can use them. Great! However, typing out
`phrases::english::greetings::hello()` is very long and repetitive. Rust has
another keyword for importing names into the current scope, so that you can
-refer to them with shorter names. Let's talk about `use`.
+refer to them with shorter names. Let’s talk about `use`.
# Importing Modules with `use`
Rust has a `use` keyword, which allows us to import names into our local scope.
-Let's change our `src/main.rs` to look like this:
+Let’s change our `src/main.rs` to look like this:
```{rust,ignore}
extern crate phrases;
```
The two `use` lines import each module into the local scope, so we can refer to
-the functions by a much shorter name. By convention, when importing functions, it's
+the functions by a much shorter name. By convention, when importing functions, it’s
considered best practice to import the module, rather than the function directly. In
other words, you _can_ do this:
```
But it is not idiomatic. This is significantly more likely to introduce a
-naming conflict. In our short program, it's not a big deal, but as it grows, it
+naming conflict. In our short program, it’s not a big deal, but as it grows, it
becomes a problem. If we have conflicting names, Rust will give a compilation
error. For example, if we made the `japanese` functions public, and tried to do
this:
Could not compile `phrases`.
```
-If we're importing multiple names from the same module, we don't have to type it out
+If we’re importing multiple names from the same module, we don’t have to type it out
twice. Instead of this:
```{rust,ignore}
## Re-exporting with `pub use`
-You don't just use `use` to shorten identifiers. You can also use it inside of your crate
+You don’t just use `use` to shorten identifiers. You can also use it inside of your crate
to re-export a function inside another module. This allows you to present an external
interface that may not directly map to your internal code organization.
-Let's look at an example. Modify your `src/main.rs` to read like this:
+Let’s look at an example. Modify your `src/main.rs` to read like this:
```{rust,ignore}
extern crate phrases;
```
The `pub use` declaration brings the function into scope at this part of our
-module hierarchy. Because we've `pub use`d this inside of our `japanese`
+module hierarchy. Because we’ve `pub use`d this inside of our `japanese`
module, we now have a `phrases::japanese::hello()` function and a
`phrases::japanese::goodbye()` function, even though the code for them lives in
`phrases::japanese::greetings::hello()` and
-`phrases::japanese::farewells::goodbye()`. Our internal organization doesn't
+`phrases::japanese::farewells::goodbye()`. Our internal organization doesn’t
define our external interface.
Here we have a `pub use` for each function we want to bring into the
What about the `self`? Well, by default, `use` declarations are absolute paths,
starting from your crate root. `self` makes that path relative to your current
-place in the hierarchy instead. There's one more special form of `use`: you can
+place in the hierarchy instead. There’s one more special form of `use`: you can
`use super::` to reach one level up the tree from your current location. Some
-people like to think of `self` as `.` and `super` as `..`, from many shells'
+people like to think of `self` as `.` and `super` as `..`, from many shells’
display for the current directory and the parent directory.
Outside of `use`, paths are relative: `foo::bar()` refers to a function inside
-of `foo` relative to where we are. If that's prefixed with `::`, as in
+of `foo` relative to where we are. If that’s prefixed with `::`, as in
`::foo::bar()`, it refers to a different `foo`, an absolute path from your
crate root.
% Macros
-By now you've learned about many of the tools Rust provides for abstracting and
+By now you’ve learned about many of the tools Rust provides for abstracting and
reusing code. These units of code reuse have a rich semantic structure. For
example, functions have a type signature, type parameters have trait bounds,
and overloaded functions must belong to a particular trait.
-This structure means that Rust's core abstractions have powerful compile-time
+This structure means that Rust’s core abstractions have powerful compile-time
correctness checking. But this comes at the price of reduced flexibility. If
-you visually identify a pattern of repeated code, you may find it's difficult
+you visually identify a pattern of repeated code, you may find it’s difficult
or cumbersome to express that pattern as a generic function, a trait, or
-anything else within Rust's semantics.
+anything else within Rust’s semantics.
-Macros allow us to abstract at a *syntactic* level. A macro invocation is
+Macros allow us to abstract at a syntactic level. A macro invocation is
shorthand for an "expanded" syntactic form. This expansion happens early in
compilation, before any static checking. As a result, macros can capture many
-patterns of code reuse that Rust's core abstractions cannot.
+patterns of code reuse that Rust’s core abstractions cannot.
The drawback is that macro-based code can be harder to understand, because
fewer of the built-in rules apply. Like an ordinary function, a well-behaved
macro code are harder to interpret, because they describe problems in the
expanded code, not the source-level form that developers use.
-These drawbacks make macros something of a "feature of last resort". That's not
-to say that macros are bad; they are part of Rust because sometimes they're
+These drawbacks make macros something of a "feature of last resort". That’s not
+to say that macros are bad; they are part of Rust because sometimes they’re
needed for truly concise, well-abstracted code. Just keep this tradeoff in
mind.
# assert_eq!(x, [1, 2, 3]);
```
-This can't be an ordinary function, because it takes any number of arguments.
+This can’t be an ordinary function, because it takes any number of arguments.
But we can imagine it as syntactic shorthand for
```rust
# }
```
-Whoa, that's a lot of new syntax! Let's break it down.
+Whoa, that’s a lot of new syntax! Let’s break it down.
```ignore
macro_rules! vec { ... }
```
-This says we're defining a macro named `vec`, much as `fn vec` would define a
-function named `vec`. In prose, we informally write a macro's name with an
+This says we’re defining a macro named `vec`, much as `fn vec` would define a
+function named `vec`. In prose, we informally write a macro’s name with an
exclamation point, e.g. `vec!`. The exclamation point is part of the invocation
syntax and serves to distinguish a macro from an ordinary function.
## Matching
-The macro is defined through a series of *rules*, which are pattern-matching
+The macro is defined through a series of rules, which are pattern-matching
cases. Above, we had
```ignore
This is like a `match` expression arm, but the matching happens on Rust syntax
trees, at compile time. The semicolon is optional on the last (here, only)
-case. The "pattern" on the left-hand side of `=>` is known as a *matcher*.
+case. The "pattern" on the left-hand side of `=>` is known as a ‘matcher’.
These have [their own little grammar] within the language.
[their own little grammar]: ../reference.html#macros
The matcher `$x:expr` will match any Rust expression, binding that syntax tree
-to the *metavariable* `$x`. The identifier `expr` is a *fragment specifier*;
+to the ‘metavariable’ `$x`. The identifier `expr` is a ‘fragment specifier’;
the full possibilities are enumerated in the [advanced macros chapter][].
Surrounding the matcher with `$(...),*` will match zero or more expressions,
separated by commas.
macro expansion. The repetition in the expansion proceeds in "lockstep" with
repetition in the matcher (more on this in a moment).
-Because `$x` was already declared as matching an expression, we don't repeat
-`:expr` on the right-hand side. Also, we don't include a separating comma as
+Because `$x` was already declared as matching an expression, we don’t repeat
+`:expr` on the right-hand side. Also, we don’t include a separating comma as
part of the repetition operator. Instead, we have a terminating semicolon
within the repeated block.
The inner braces are part of the expanded syntax. Remember, the `vec!` macro is
used in an expression context. To write an expression with multiple statements,
including `let`-bindings, we use a block. If your macro expands to a single
-expression, you don't need this extra layer of braces.
+expression, you don’t need this extra layer of braces.
Note that we never *declared* that the macro produces an expression. In fact,
this is not determined until we use the macro as an expression. With care, you
1. `$(...)*` walks through one "layer" of repetitions, for all of the `$name`s
it contains, in lockstep, and
2. each `$name` must be under at least as many `$(...)*`s as it was matched
- against. If it is under more, it'll be duplicated, as appropriate.
+ against. If it is under more, it’ll be duplicated, as appropriate.
This baroque macro illustrates the duplication of variables from outer
repetition levels.
}
```
-That's most of the matcher syntax. These examples use `$(...)*`, which is a
+That’s most of the matcher syntax. These examples use `$(...)*`, which is a
"zero or more" match. Alternatively you can write `$(...)+` for a "one or
more" match. Both forms optionally include a separator, which can be any token
except `+` or `*`.
```
After expansion we have `5 * 2 + 3`, and multiplication has greater precedence
-than addition. If you've used C macros a lot, you probably know the standard
+than addition. If you’ve used C macros a lot, you probably know the standard
idioms for avoiding this problem, as well as five or six others. In Rust, we
-don't have to worry about it.
+don’t have to worry about it.
```rust
macro_rules! five_times {
The metavariable `$x` is parsed as a single expression node, and keeps its
place in the syntax tree even after substitution.
-Another common problem in macro systems is *variable capture*. Here's a C
-macro, using [a GNU C extension] to emulate Rust's expression blocks.
+Another common problem in macro systems is ‘variable capture’. Here’s a C
+macro, using [a GNU C extension] to emulate Rust’s expression blocks.
[a GNU C extension]: https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html
})
```
-Here's a simple use case that goes terribly wrong:
+Here’s a simple use case that goes terribly wrong:
```text
const char *state = "reticulating splines";
```
This works because Rust has a [hygienic macro system][]. Each macro expansion
-happens in a distinct *syntax context*, and each variable is tagged with the
-syntax context where it was introduced. It's as though the variable `state`
+happens in a distinct ‘syntax context’, and each variable is tagged with the
+syntax context where it was introduced. It’s as though the variable `state`
inside `main` is painted a different "color" from the variable `state` inside
-the macro, and therefore they don't conflict.
+the macro, and therefore they don’t conflict.
[hygienic macro system]: http://en.wikipedia.org/wiki/Hygienic_macro
}
```
-Instead you need to pass the variable name into the invocation, so it's tagged
+Instead you need to pass the variable name into the invocation, so it’s tagged
with the right syntax context.
```rust
# Recursive macros
-A macro's expansion can include more macro invocations, including invocations
+A macro’s expansion can include more macro invocations, including invocations
of the very same macro being expanded. These recursive macros are useful for
processing tree-structured input, as illustrated by this (simplistic) HTML
shorthand:
Even when Rust code contains un-expanded macros, it can be parsed as a full
[syntax tree][ast]. This property can be very useful for editors and other
tools that process code. It also has a few consequences for the design of
-Rust's macro system.
+Rust’s macro system.
[ast]: glossary.html#abstract-syntax-tree
must be balanced within a macro invocation. For example, `foo!([)` is
forbidden. This allows Rust to know where the macro invocation ends.
-More formally, the macro invocation body must be a sequence of *token trees*.
+More formally, the macro invocation body must be a sequence of ‘token trees’.
A token tree is defined recursively as either
* a sequence of token trees surrounded by matching `()`, `[]`, or `{}`, or
* any other single token.
-Within a matcher, each metavariable has a *fragment specifier*, identifying
+Within a matcher, each metavariable has a ‘fragment specifier’, identifying
which syntactic form it matches.
* `ident`: an identifier. Examples: `x`; `foo`.
* `pat` variables must be followed by one of: `=> , =`
* Other variables may be followed by any token.
-These rules provide some flexibility for Rust's syntax to evolve without
+These rules provide some flexibility for Rust’s syntax to evolve without
breaking existing macros.
The macro system does not deal with parse ambiguity at all. For example, the
constructs in the language.
Definition and expansion of macros both happen in a single depth-first,
-lexical-order traversal of a crate's source. So a macro defined at module scope
+lexical-order traversal of a crate’s source. So a macro defined at module scope
is visible to any subsequent code in the same module, which includes the body
of any subsequent child `mod` items.
module scope, is visible only within that item.
If a module has the `macro_use` attribute, its macros are also visible in its
-parent module after the child's `mod` item. If the parent also has `macro_use`
-then the macros will be visible in the grandparent after the parent's `mod`
+parent module after the child’s `mod` item. If the parent also has `macro_use`
+then the macros will be visible in the grandparent after the parent’s `mod`
item, and so forth.
The `macro_use` attribute can also appear on `extern crate`. In this context
there is no `#[macro_use]` attribute then no macros are loaded. Only macros
defined with the `#[macro_export]` attribute may be loaded.
-To load a crate's macros *without* linking it into the output, use `#[no_link]`
+To load a crate’s macros without linking it into the output, use `#[no_link]`
as well.
An example:
The introductory chapter mentioned recursive macros, but it did not give the
full story. Recursive macros are useful for another reason: Each recursive
-invocation gives you another opportunity to pattern-match the macro's
+invocation gives you another opportunity to pattern-match the macro’s
arguments.
As an extreme example, it is possible, though hardly advisable, to implement
the [Bitwise Cyclic Tag](http://esolangs.org/wiki/Bitwise_Cyclic_Tag) automaton
-within Rust's macro system.
+within Rust’s macro system.
```rust
macro_rules! bct {
# Procedural macros
-If Rust's macro system can't do what you need, you may want to write a
+If Rust’s macro system can’t do what you need, you may want to write a
[compiler plugin](plugins.html) instead. Compared to `macro_rules!`
macros, this is significantly more work, the interfaces are much less stable,
and bugs can be much harder to track down. In exchange you get the
flexibility of running arbitrary Rust code within the compiler. Syntax
-extension plugins are sometimes called *procedural macros* for this reason.
+extension plugins are sometimes called ‘procedural macros’ for this reason.
% Trait Objects
When code involves polymorphism, there needs to be a mechanism to determine
-which specific version is actually run. This is called 'dispatch.' There are
+which specific version is actually run. This is called ‘dispatch’. There are
two major forms of dispatch: static dispatch and dynamic dispatch. While Rust
favors static dispatch, it also supports dynamic dispatch through a mechanism
-called 'trait objects.'
+called ‘trait objects’.
## Background
-For the rest of this chapter, we'll need a trait and some implementations.
-Let's make a simple one, `Foo`. It has one method that is expected to return a
+For the rest of this chapter, we’ll need a trait and some implementations.
+Let’s make a simple one, `Foo`. It has one method that is expected to return a
`String`.
```rust
}
```
-We'll also implement this trait for `u8` and `String`:
+We’ll also implement this trait for `u8` and `String`:
```rust
# trait Foo { fn method(&self) -> String; }
}
```
-Rust uses 'monomorphization' to perform static dispatch here. This means that
+Rust uses ‘monomorphization’ to perform static dispatch here. This means that
Rust will create a special version of `do_something()` for both `u8` and
`String`, and then replace the call sites with calls to these specialized
functions. In other words, Rust generates something like this:
This has a great upside: static dispatch allows function calls to be
inlined because the callee is known at compile time, and inlining is
the key to good optimization. Static dispatch is fast, but it comes at
-a tradeoff: 'code bloat', due to many copies of the same function
+a tradeoff: ‘code bloat’, due to many copies of the same function
existing in the binary, one for each type.
Furthermore, compilers aren’t perfect and may “optimize” code to become slower.
## Dynamic dispatch
-Rust provides dynamic dispatch through a feature called 'trait objects.' Trait
+Rust provides dynamic dispatch through a feature called ‘trait objects’. Trait
objects, like `&Foo` or `Box<Foo>`, are normal values that store a value of
*any* type that implements the given trait, where the precise type can only be
known at runtime.
(e.g. using `&x` as an argument to a function that takes `&Foo`).
These trait object coercions and casts also work for pointers like `&mut T` to
-`&mut Foo` and `Box<T>` to `Box<Foo>`, but that's all at the moment. Coercions
+`&mut Foo` and `Box<T>` to `Box<Foo>`, but that’s all at the moment. Coercions
and casts are identical.
-This operation can be seen as "erasing" the compiler's knowledge about the
+This operation can be seen as ‘erasing’ the compiler’s knowledge about the
specific type of the pointer, and hence trait objects are sometimes referred to
-as "type erasure".
+as ‘type erasure’.
Coming back to the example above, we can use the same trait to perform dynamic
dispatch with trait objects by casting:
For `Foo`, we would need to have a value that could be at least either a
`String` (24 bytes) or a `u8` (1 byte), as well as any other type for which
-dependent crates may implement `Foo` (any number of bytes at all). There's no
+dependent crates may implement `Foo` (any number of bytes at all). There’s no
way to guarantee that this last point can work if the values are stored without
a pointer, because those other types can be arbitrarily large.
### Representation
The methods of the trait can be called on a trait object via a special record
-of function pointers traditionally called a 'vtable' (created and managed by
+of function pointers traditionally called a ‘vtable’ (created and managed by
the compiler).
Trait objects are both simple and complicated: their core representation and
layout is quite straight-forward, but there are some curly error messages and
surprising behaviors to discover.
-Let's start simple, with the runtime representation of a trait object. The
+Let’s start simple, with the runtime representation of a trait object. The
`std::raw` module contains structs with layouts that are the same as the
complicated built-in types, [including trait objects][stdraw]:
[stdraw]: ../std/raw/struct.TraitObject.html
-That is, a trait object like `&Foo` consists of a "data" pointer and a "vtable"
+That is, a trait object like `&Foo` consists of a ‘data’ pointer and a ‘vtable’
pointer.
The data pointer addresses the data (of some unknown type `T`) that the trait
-object is storing, and the vtable pointer points to the vtable ("virtual method
-table") corresponding to the implementation of `Foo` for `T`.
+object is storing, and the vtable pointer points to the vtable (‘virtual method
+table’) corresponding to the implementation of `Foo` for `T`.
A vtable is essentially a struct of function pointers, pointing to the concrete
`trait_object.method()` will retrieve the correct pointer out of the vtable and
then do a dynamic call of it. For example:
-```{rust,ignore}
+```rust,ignore
struct FooVtable {
destructor: fn(*mut ()),
size: usize,
```
The `destructor` field in each vtable points to a function that will clean up
-any resources of the vtable's type, for `u8` it is trivial, but for `String` it
+any resources of the vtable’s type, for `u8` it is trivial, but for `String` it
will free the memory. This is necessary for owning trait objects like
`Box<Foo>`, which need to clean-up both the `Box` allocation as well as the
internal type when they go out of scope. The `size` and `align` fields store
destructor, but will be used in the future, as trait objects are progressively
made more flexible.
-Suppose we've got some values that implement `Foo`, then the explicit form of
+Suppose we’ve got some values that implement `Foo`, then the explicit form of
construction and use of `Foo` trait objects might look a bit like (ignoring the
-type mismatches: they're all just pointers anyway):
+type mismatches: they’re all just pointers anyway):
-```{rust,ignore}
+```rust,ignore
let a: String = "foo".to_string();
let x: u8 = 1;