Skip to content

Commit

Permalink
remove first edition content
Browse files Browse the repository at this point in the history
  • Loading branch information
steveklabnik committed Nov 20, 2018
1 parent fc4274d commit 768a389
Show file tree
Hide file tree
Showing 58 changed files with 343 additions and 16,954 deletions.
41 changes: 6 additions & 35 deletions first-edition/src/README.md
Original file line number Diff line number Diff line change
@@ -1,39 +1,10 @@
# The Rust Programming Language

Welcome! This book will teach you about the [Rust Programming Language][rust].
Rust is a systems programming language focused on three goals: safety, speed,
and concurrency. It maintains these goals without having a garbage collector,
making it a useful language for a number of use cases other languages aren’t
good at: embedding in other languages, programs with specific space and time
requirements, and writing low-level code, like device drivers and operating
systems. It improves on current languages targeting this space by having a
number of compile-time safety checks that produce no runtime overhead, while
eliminating all data races. Rust also aims to achieve ‘zero-cost abstractions’
even though some of these abstractions feel like those of a high-level language.
Even then, Rust still allows precise control like a low-level language would.
The first edition of the book is no longer distributed with Rust's documentation.

[rust]: https://www.rust-lang.org
If you came here via a link or web search, you may want to check out [the current
version of the book](../index.html) instead.

“The Rust Programming Language” is split into chapters. This introduction
is the first. After this:

* [Getting started][gs] - Set up your computer for Rust development.
* [Tutorial: Guessing Game][gg] - Learn some Rust with a small project.
* [Syntax and Semantics][ss] - Each bit of Rust, broken down into small chunks.
* [Effective Rust][er] - Higher-level concepts for writing excellent Rust code.
* [Glossary][gl] - A reference of terms used in the book.
* [Bibliography][bi] - Background on Rust's influences, papers about Rust.

[gs]: getting-started.html
[gg]: guessing-game.html
[er]: effective-rust.html
[ss]: syntax-and-semantics.html
[gl]: glossary.html
[bi]: bibliography.html

## Source Code

The source files from which this book is generated can be found on
[GitHub][book].

[book]: https://github.com/rust-lang/book/tree/master/first-edition/src
If you have an internet connection, you can [find a copy distributed with
Rust
1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/README.html).
204 changes: 6 additions & 198 deletions first-edition/src/associated-types.md
Original file line number Diff line number Diff line change
@@ -1,202 +1,10 @@
# 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
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:
The first edition of the book is no longer distributed with Rust's documentation.

```rust
trait Graph<N, E> {
fn has_edge(&self, &N, &N) -> bool;
fn edges(&self, &N) -> Vec<E>;
// Etc.
}
```
If you came here via a link or web search, you may want to check out [the current
version of the book](../index.html) instead.

While this sort of works, it ends up being awkward. For example, any function
that wants to take a `Graph` as a parameter now _also_ needs to be generic over
the `N`ode and `E`dge types too:

```rust,ignore
fn distance<N, E, G: Graph<N, E>>(graph: &G, start: &N, end: &N) -> u32 { ... }
```

Our distance calculation works regardless of our `Edge` type, so the `E` stuff in
this signature is a distraction.

What we really want to say is that a certain `E`dge and `N`ode type come together
to form each kind of `Graph`. We can do that with associated types:

```rust
trait Graph {
type N;
type E;

fn has_edge(&self, &Self::N, &Self::N) -> bool;
fn edges(&self, &Self::N) -> Vec<Self::E>;
// Etc.
}
```

Now, our clients can be abstract over a given `Graph`:

```rust,ignore
fn distance<G: Graph>(graph: &G, start: &G::N, end: &G::N) -> u32 { ... }
```

No need to deal with the `E`dge type here!

Let’s go over all this in more detail.

## Defining associated types

Let’s build that `Graph` trait. Here’s the definition:

```rust
trait Graph {
type N;
type E;

fn has_edge(&self, &Self::N, &Self::N) -> bool;
fn edges(&self, &Self::N) -> Vec<Self::E>;
}
```

Simple enough. Associated types use the `type` keyword, and go inside the body
of the trait, with the functions.

These type declarations work the same way as those for functions. For example,
if we wanted our `N` type to implement `Display`, so we can print the nodes out,
we could do this:

```rust
use std::fmt;

trait Graph {
type N: fmt::Display;
type E;

fn has_edge(&self, &Self::N, &Self::N) -> bool;
fn edges(&self, &Self::N) -> Vec<Self::E>;
}
```

## 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:

```rust
# trait Graph {
# type N;
# type E;
# fn has_edge(&self, &Self::N, &Self::N) -> bool;
# fn edges(&self, &Self::N) -> Vec<Self::E>;
# }
struct Node;

struct Edge;

struct MyGraph;

impl Graph for MyGraph {
type N = Node;
type E = Edge;

fn has_edge(&self, n1: &Node, n2: &Node) -> bool {
true
}

fn edges(&self, n: &Node) -> Vec<Edge> {
Vec::new()
}
}
```

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 going to
use `struct`s for all three here.

Next is the `impl` line, which is an implementation like 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
for goes on the right. Finally, we use the concrete types in our function
declarations.

## Trait objects with associated types

There’s one more bit of syntax we should talk about: trait objects. If you
try to create a trait object from a trait with an associated type, like this:

```rust,ignore
# trait Graph {
# type N;
# type E;
# fn has_edge(&self, &Self::N, &Self::N) -> bool;
# fn edges(&self, &Self::N) -> Vec<Self::E>;
# }
# struct Node;
# struct Edge;
# struct MyGraph;
# impl Graph for MyGraph {
# type N = Node;
# type E = Edge;
# fn has_edge(&self, n1: &Node, n2: &Node) -> bool {
# true
# }
# fn edges(&self, n: &Node) -> Vec<Edge> {
# Vec::new()
# }
# }
let graph = MyGraph;
let obj = Box::new(graph) as Box<Graph>;
```

You’ll get two errors:

```text
error: the value of the associated type `E` (from the trait `main::Graph`) must
be specified [E0191]
let obj = Box::new(graph) as Box<Graph>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24:44 error: the value of the associated type `N` (from the trait
`main::Graph`) must be specified [E0191]
let obj = Box::new(graph) as Box<Graph>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```

We can’t create a trait object like this, because we don’t know the associated
types. Instead, we can write this:

```rust
# trait Graph {
# type N;
# type E;
# fn has_edge(&self, &Self::N, &Self::N) -> bool;
# fn edges(&self, &Self::N) -> Vec<Self::E>;
# }
# struct Node;
# struct Edge;
# struct MyGraph;
# impl Graph for MyGraph {
# type N = Node;
# type E = Edge;
# fn has_edge(&self, n1: &Node, n2: &Node) -> bool {
# true
# }
# fn edges(&self, n: &Node) -> Vec<Edge> {
# Vec::new()
# }
# }
let graph = MyGraph;
let obj = Box::new(graph) as Box<Graph<N=Node, E=Edge>>;
```

The `N=Node` syntax allows us to provide a concrete type, `Node`, for the `N`
type parameter. Same with `E=Edge`. If we didn’t provide this constraint, we
couldn’t be sure which `impl` to match this trait object to.
If you have an internet connection, you can [find a copy distributed with
Rust
1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/associated-types.html).
72 changes: 6 additions & 66 deletions first-edition/src/attributes.md
Original file line number Diff line number Diff line change
@@ -1,70 +1,10 @@
# Attributes

Declarations can be annotated with ‘attributes’ in Rust. They look like this:
The first edition of the book is no longer distributed with Rust's documentation.

```rust
#[test]
# fn foo() {}
```
If you came here via a link or web search, you may want to check out [the current
version of the book](../index.html) instead.

or like this:

```rust
# mod foo {
#![test]
# }
```

The difference between the two is the `!`, which changes what the attribute
applies to:

```rust,ignore
#[foo]
struct Foo;
mod bar {
#![bar]
}
```

The `#[foo]` attribute applies to the next item, which is the `struct`
declaration. The `#![bar]` attribute applies to the item enclosing it, which is
the `mod` declaration. Otherwise, they’re the same. Both change the meaning of
the item they’re attached to somehow.

For example, consider a function like this:

```rust
#[test]
fn check() {
assert_eq!(2, 1 + 1);
}
```

It is marked with `#[test]`. This means it’s special: when you run
[tests][tests], this function will execute. When you compile as usual, it won’t
even be included. This function is now a test function.

[tests]: testing.html

Attributes may also have additional data:

```rust
#[inline(always)]
fn super_fast_fn() {
# }
```

Or even keys and values:

```rust
#[cfg(target_os = "macos")]
mod macos_only {
# }
```

Rust attributes are used for a number of different things. There is a full list
of attributes [in the reference][reference]. Currently, you are not allowed to
create your own attributes, the Rust compiler defines them.

[reference]: ../../reference/attributes.html
If you have an internet connection, you can [find a copy distributed with
Rust
1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/attributes.html).
Loading

0 comments on commit 768a389

Please sign in to comment.