forked from rust-lang/book
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
fc4274d
commit 768a389
Showing
58 changed files
with
343 additions
and
16,954 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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). |
Oops, something went wrong.