]> git.proxmox.com Git - rustc.git/blame - src/doc/trpl/README.md
Imported Upstream version 1.2.0+dfsg1
[rustc.git] / src / doc / trpl / README.md
CommitLineData
1a4d82fc
JJ
1% The Rust Programming Language
2
9346a6ac
AL
3Welcome! This book will teach you about the [Rust Programming Language][rust].
4Rust is a systems programming language focused on three goals: safety, speed,
5and concurrency. It maintains these goals without having a garbage collector,
6making it a useful language for a number of use cases other languages aren’t
7good at: embedding in other languages, programs with specific space and time
8requirements, and writing low-level code, like device drivers and operating
9systems. It improves on current languages targeting this space by having a
10number of compile-time safety checks that produce no runtime overhead, while
bd371182 11eliminating all data races. Rust also aims to achieve ‘zero-cost abstractions’
9346a6ac
AL
12even though some of these abstractions feel like those of a high-level
13language. Even then, Rust still allows precise control like a low-level
14language would.
1a4d82fc 15
9346a6ac 16[rust]: http://rust-lang.org
1a4d82fc 17
62682a34 18“The Rust Programming Language” is split into eight sections. This introduction
9346a6ac 19is the first. After this:
1a4d82fc 20
9346a6ac
AL
21* [Getting started][gs] - Set up your computer for Rust development.
22* [Learn Rust][lr] - Learn Rust programming through small projects.
23* [Effective Rust][er] - Higher-level concepts for writing excellent Rust code.
24* [Syntax and Semantics][ss] - Each bit of Rust, broken down into small chunks.
25* [Nightly Rust][nr] - Cutting-edge features that aren’t in stable builds yet.
26* [Glossary][gl] - A reference of terms used in the book.
bd371182 27* [Academic Research][ar] - Literature that influenced Rust.
1a4d82fc 28
9346a6ac
AL
29[gs]: getting-started.html
30[lr]: learn-rust.html
31[er]: effective-rust.html
32[ss]: syntax-and-semantics.html
33[nr]: nightly-rust.html
34[gl]: glossary.html
bd371182 35[ar]: academic-research.html
1a4d82fc 36
9346a6ac
AL
37After reading this introduction, you’ll want to dive into either ‘Learn Rust’
38or ‘Syntax and Semantics’, depending on your preference: ‘Learn Rust’ if you
39want to dive in with a project, or ‘Syntax and Semantics’ if you prefer to
40start small, and learn a single concept thoroughly before moving onto the next.
41Copious cross-linking connects these parts together.
1a4d82fc 42
bd371182
AL
43### Contributing
44
45The source files from which this book is generated can be found on Github:
46[github.com/rust-lang/rust/tree/master/src/doc/trpl](https://github.com/rust-lang/rust/tree/master/src/doc/trpl)
47
9346a6ac 48## A brief introduction to Rust
1a4d82fc 49
9346a6ac
AL
50Is Rust a language you might be interested in? Let’s examine a few small code
51samples to show off a few of its strengths.
1a4d82fc 52
9346a6ac
AL
53The main concept that makes Rust unique is called ‘ownership’. Consider this
54small example:
1a4d82fc 55
9346a6ac
AL
56```rust
57fn main() {
58 let mut x = vec!["Hello", "world"];
59}
60```
1a4d82fc 61
9346a6ac
AL
62This program makes a [variable binding][var] named `x`. The value of this
63binding is a `Vec<T>`, a ‘vector’, that we create through a [macro][macro]
64defined in the standard library. This macro is called `vec`, and we invoke
65macros with a `!`. This follows a general principle of Rust: make things
66explicit. Macros can do significantly more complicated things than function
67calls, and so they’re visually distinct. The `!` also helps with parsing,
68making tooling easier to write, which is also important.
c34b1796 69
9346a6ac
AL
70We used `mut` to make `x` mutable: bindings are immutable by default in Rust.
71We’ll be mutating this vector later in the example.
c34b1796 72
9346a6ac
AL
73It’s also worth noting that we didn’t need a type annotation here: while Rust
74is statically typed, we didn’t need to explicitly annotate the type. Rust has
75type inference to balance out the power of static typing with the verbosity of
76annotating types.
77
78Rust prefers stack allocation to heap allocation: `x` is placed directly on the
79stack. However, the `Vec<T>` type allocates space for the elements of the
80vector on the heap. If you’re not familiar with this distinction, you can
81ignore it for now, or check out [‘The Stack and the Heap’][heap]. As a systems
82programming language, Rust gives you the ability to control how your memory is
83allocated, but when we’re getting started, it’s less of a big deal.
84
85[var]: variable-bindings.html
86[macro]: macros.html
87[heap]: the-stack-and-the-heap.html
88
89Earlier, we mentioned that ‘ownership’ is the key new concept in Rust. In Rust
90parlance, `x` is said to ‘own’ the vector. This means that when `x` goes out of
91scope, the vector’s memory will be de-allocated. This is done deterministically
92by the Rust compiler, rather than through a mechanism such as a garbage
93collector. In other words, in Rust, you don’t call functions like `malloc` and
94`free` yourself: the compiler statically determines when you need to allocate
95or deallocate memory, and inserts those calls itself. To err is to be human,
96but compilers never forget.
97
98Let’s add another line to our example:
99
100```rust
101fn main() {
102 let mut x = vec!["Hello", "world"];
103
104 let y = &x[0];
105}
106```
107
108We’ve introduced another binding, `y`. In this case, `y` is a ‘reference’ to
109the first element of the vector. Rust’s references are similar to pointers in
110other languages, but with additional compile-time safety checks. References
111interact with the ownership system by [‘borrowing’][borrowing] what they point
112to, rather than owning it. The difference is, when the reference goes out of
113scope, it will not deallocate the underlying memory. If it did, we’d
114de-allocate twice, which is bad!
115
116[borrowing]: references-and-borrowing.html
117
118Let’s add a third line. It looks innocent enough, but causes a compiler error:
119
120```rust,ignore
121fn main() {
122 let mut x = vec!["Hello", "world"];
123
124 let y = &x[0];
125
126 x.push("foo");
127}
128```
129
130`push` is a method on vectors that appends another element to the end of the
131vector. When we try to compile this program, we get an error:
132
133```text
134error: cannot borrow `x` as mutable because it is also borrowed as immutable
bd371182 135 x.push("foo");
9346a6ac
AL
136 ^
137note: previous borrow of `x` occurs here; the immutable borrow prevents
138subsequent moves or mutable borrows of `x` until the borrow ends
139 let y = &x[0];
140 ^
141note: previous borrow ends here
142fn main() {
143
144}
145^
146```
147
148Whew! The Rust compiler gives quite detailed errors at times, and this is one
149of those times. As the error explains, while we made our binding mutable, we
150still cannot call `push`. This is because we already have a reference to an
151element of the vector, `y`. Mutating something while another reference exists
152is dangerous, because we may invalidate the reference. In this specific case,
62682a34
SL
153when we create the vector, we may have only allocated space for two elements.
154Adding a third would mean allocating a new chunk of memory for all those elements,
9346a6ac
AL
155copying the old values over, and updating the internal pointer to that memory.
156That all works just fine. The problem is that `y` wouldn’t get updated, and so
157we’d have a ‘dangling pointer’. That’s bad. Any use of `y` would be an error in
158this case, and so the compiler has caught this for us.
159
160So how do we solve this problem? There are two approaches we can take. The first
161is making a copy rather than using a reference:
162
163```rust
164fn main() {
165 let mut x = vec!["Hello", "world"];
166
167 let y = x[0].clone();
168
169 x.push("foo");
170}
171```
172
173Rust has [move semantics][move] by default, so if we want to make a copy of some
174data, we call the `clone()` method. In this example, `y` is no longer a reference
bd371182 175to the vector stored in `x`, but a copy of its first element, `"Hello"`. Now
9346a6ac
AL
176that we don’t have a reference, our `push()` works just fine.
177
d9579d0f 178[move]: ownership.html#move-semantics
9346a6ac
AL
179
180If we truly want a reference, we need the other option: ensure that our reference
181goes out of scope before we try to do the mutation. That looks like this:
182
183```rust
184fn main() {
185 let mut x = vec!["Hello", "world"];
186
187 {
188 let y = &x[0];
189 }
190
191 x.push("foo");
192}
193```
194
195We created an inner scope with an additional set of curly braces. `y` will go out of
196scope before we call `push()`, and so we’re all good.
197
bd371182 198This concept of ownership isn’t just good for preventing dangling pointers, but an
9346a6ac 199entire set of related problems, like iterator invalidation, concurrency, and more.