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