Skip to content

Commit 330466e

Browse files
committed
rollup merge of rust-lang#24273: steveklabnik/even_moar_editing
Three more sections
2 parents fb956dc + 6476a1e commit 330466e

File tree

3 files changed

+148
-76
lines changed

3 files changed

+148
-76
lines changed

src/doc/trpl/comments.md

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,45 @@
11
% Comments
22

3-
Now that we have some functions, it's a good idea to learn about comments.
3+
Now that we have some functions, its a good idea to learn about comments.
44
Comments are notes that you leave to other programmers to help explain things
55
about your code. The compiler mostly ignores them.
66

77
Rust has two kinds of comments that you should care about: *line comments*
88
and *doc comments*.
99

10-
```{rust}
11-
// Line comments are anything after '//' and extend to the end of the line.
10+
```rust
11+
// Line comments are anything after ‘//’ and extend to the end of the line.
1212

1313
let x = 5; // this is also a line comment.
1414

1515
// If you have a long explanation for something, you can put line comments next
16-
// to each other. Put a space between the // and your comment so that it's
16+
// to each other. Put a space between the // and your comment so that its
1717
// more readable.
1818
```
1919

2020
The other kind of comment is a doc comment. Doc comments use `///` instead of
2121
`//`, and support Markdown notation inside:
2222

23-
```{rust}
24-
/// `hello` is a function that prints a greeting that is personalized based on
25-
/// the name given.
26-
///
27-
/// # Arguments
28-
///
29-
/// * `name` - The name of the person you'd like to greet.
23+
```rust
24+
/// Adds one to the number given.
3025
///
3126
/// # Examples
3227
///
33-
/// ```rust
34-
/// let name = "Steve";
35-
/// hello(name); // prints "Hello, Steve!"
3628
/// ```
37-
fn hello(name: &str) {
38-
println!("Hello, {}!", name);
29+
/// let five = 5;
30+
///
31+
/// assert_eq!(6, add_one(5));
32+
/// ```
33+
fn add_one(x: i32) -> i32 {
34+
x + 1
3935
}
4036
```
4137

42-
When writing doc comments, adding sections for any arguments, return values,
43-
and providing some examples of usage is very, very helpful. Don't worry about
44-
the `&str`, we'll get to it soon.
38+
When writing doc comments, providing some examples of usage is very, very
39+
helpful. You’ll notice we’ve used a new macro here: `assert_eq!`. This compares
40+
two values, and `panic!`s if they’re not equal to each other. It’s very helpful
41+
in documentation. There’s another macro, `assert!`, which `panic!`s if the
42+
value passed to it is `false`.
4543

4644
You can use the [`rustdoc`](documentation.html) tool to generate HTML documentation
47-
from these doc comments.
45+
from these doc comments, and also to run the code examples as tests!

src/doc/trpl/functions.md

Lines changed: 85 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
11
% Functions
22

3-
You've already seen one function so far, the `main` function:
3+
Every Rust program has at least one function, the `main` function:
44

55
```rust
66
fn main() {
77
}
88
```
99

1010
This is the simplest possible function declaration. As we mentioned before,
11-
`fn` says "this is a function," followed by the name, some parentheses because
11+
`fn` says this is a function’, followed by the name, some parentheses because
1212
this function takes no arguments, and then some curly braces to indicate the
13-
body. Here's a function named `foo`:
13+
body. Heres a function named `foo`:
1414

1515
```rust
1616
fn foo() {
1717
}
1818
```
1919

20-
So, what about taking arguments? Here's a function that prints a number:
20+
So, what about taking arguments? Heres a function that prints a number:
2121

2222
```rust
2323
fn print_number(x: i32) {
2424
println!("x is: {}", x);
2525
}
2626
```
2727

28-
Here's a complete program that uses `print_number`:
28+
Heres a complete program that uses `print_number`:
2929

3030
```rust
3131
fn main() {
@@ -40,7 +40,7 @@ fn print_number(x: i32) {
4040
As you can see, function arguments work very similar to `let` declarations:
4141
you add a type to the argument name, after a colon.
4242

43-
Here's a complete program that adds two numbers together and prints them:
43+
Heres a complete program that adds two numbers together and prints them:
4444

4545
```rust
4646
fn main() {
@@ -58,7 +58,7 @@ as when you declare it.
5858
Unlike `let`, you _must_ declare the types of function arguments. This does
5959
not work:
6060

61-
```{rust,ignore}
61+
```rust,ignore
6262
fn print_sum(x, y) {
6363
println!("sum is: {}", x + y);
6464
}
@@ -67,8 +67,8 @@ fn print_sum(x, y) {
6767
You get this error:
6868

6969
```text
70-
hello.rs:5:18: 5:19 expected one of `!`, `:`, or `@`, found `)`
71-
hello.rs:5 fn print_number(x, y) {
70+
expected one of `!`, `:`, or `@`, found `)`
71+
fn print_number(x, y) {
7272
```
7373

7474
This is a deliberate design decision. While full-program inference is possible,
@@ -77,7 +77,7 @@ types explicitly is a best-practice. We agree that forcing functions to declare
7777
types while allowing for inference inside of function bodies is a wonderful
7878
sweet spot between full inference and no inference.
7979

80-
What about returning a value? Here's a function that adds one to an integer:
80+
What about returning a value? Heres a function that adds one to an integer:
8181

8282
```rust
8383
fn add_one(x: i32) -> i32 {
@@ -86,11 +86,11 @@ fn add_one(x: i32) -> i32 {
8686
```
8787

8888
Rust functions return exactly one value, and you declare the type after an
89-
"arrow," which is a dash (`-`) followed by a greater-than sign (`>`).
89+
‘arrow’, which is a dash (`-`) followed by a greater-than sign (`>`). The last
90+
line of a function determines what it returns. You’ll note the lack of a
91+
semicolon here. If we added it in:
9092

91-
You'll note the lack of a semicolon here. If we added it in:
92-
93-
```{rust,ignore}
93+
```rust,ignore
9494
fn add_one(x: i32) -> i32 {
9595
x + 1;
9696
}
@@ -109,60 +109,99 @@ help: consider removing this semicolon:
109109
^
110110
```
111111

112-
Remember our earlier discussions about semicolons and `()`? Our function claims
113-
to return an `i32`, but with a semicolon, it would return `()` instead. Rust
114-
realizes this probably isn't what we want, and suggests removing the semicolon.
112+
This reveals two interesting things about Rust: it is an expression-based
113+
language, and semicolons are different from semicolons in other ‘curly brace
114+
and semicolon’-based languages. These two things are related.
115115

116-
This is very much like our `if` statement before: the result of the block
117-
(`{}`) is the value of the expression. Other expression-oriented languages,
118-
such as Ruby, work like this, but it's a bit unusual in the systems programming
119-
world. When people first learn about this, they usually assume that it
120-
introduces bugs. But because Rust's type system is so strong, and because unit
121-
is its own unique type, we have never seen an issue where adding or removing a
122-
semicolon in a return position would cause a bug.
116+
## Expressions vs. Statements
123117

124-
But what about early returns? Rust does have a keyword for that, `return`:
118+
Rust is primarily an expression-based language. There are only two kinds of
119+
statements, and everything else is an expression.
125120

126-
```rust
127-
fn foo(x: i32) -> i32 {
128-
if x < 5 { return x; }
121+
So what's the difference? Expressions return a value, and statements do not.
122+
That’s why we end up with ‘not all control paths return a value’ here: the
123+
statement `x + 1;` doesn’t return a value. There are two kinds of statements in
124+
Rust: ‘declaration statements’ and ‘expression statements’. Everything else is
125+
an expression. Let’s talk about declaration statements first.
126+
127+
In some languages, variable bindings can be written as expressions, not just
128+
statements. Like Ruby:
129+
130+
```ruby
131+
x = y = 5
132+
```
133+
134+
In Rust, however, using `let` to introduce a binding is _not_ an expression. The
135+
following will produce a compile-time error:
136+
137+
```ignore
138+
let x = (let y = 5); // expected identifier, found keyword `let`
139+
```
140+
141+
The compiler is telling us here that it was expecting to see the beginning of
142+
an expression, and a `let` can only begin a statement, not an expression.
143+
144+
Note that assigning to an already-bound variable (e.g. `y = 5`) is still an
145+
expression, although its value is not particularly useful. Unlike other
146+
languages where an assignment evaluates to the assigned value (e.g. `5` in the
147+
previous example), in Rust the value of an assignment is an empty tuple `()`:
148+
149+
```
150+
let mut y = 5;
151+
152+
let x = (y = 6); // x has the value `()`, not `6`
153+
```
154+
155+
The second kind of statement in Rust is the *expression statement*. Its
156+
purpose is to turn any expression into a statement. In practical terms, Rust's
157+
grammar expects statements to follow other statements. This means that you use
158+
semicolons to separate expressions from each other. This means that Rust
159+
looks a lot like most other languages that require you to use semicolons
160+
at the end of every line, and you will see semicolons at the end of almost
161+
every line of Rust code you see.
129162

163+
What is this exception that makes us say "almost"? You saw it already, in this
164+
code:
165+
166+
```rust
167+
fn add_one(x: i32) -> i32 {
130168
x + 1
131169
}
132170
```
133171

134-
Using a `return` as the last line of a function works, but is considered poor
135-
style:
172+
Our function claims to return an `i32`, but with a semicolon, it would return
173+
`()` instead. Rust realizes this probably isn’t what we want, and suggests
174+
removing the semicolon in the error we saw before.
175+
176+
## Early returns
177+
178+
But what about early returns? Rust does have a keyword for that, `return`:
136179

137180
```rust
138181
fn foo(x: i32) -> i32 {
139-
if x < 5 { return x; }
182+
return x;
140183

141-
return x + 1;
184+
// we never run this code!
185+
x + 1
142186
}
143187
```
144188

145-
The previous definition without `return` may look a bit strange if you haven't
146-
worked in an expression-based language before, but it becomes intuitive over
147-
time. If this were production code, we wouldn't write it in that way anyway,
148-
we'd write this:
189+
Using a `return` as the last line of a function works, but is considered poor
190+
style:
149191

150192
```rust
151193
fn foo(x: i32) -> i32 {
152-
if x < 5 {
153-
x
154-
} else {
155-
x + 1
156-
}
194+
return x + 1;
157195
}
158196
```
159197

160-
Because `if` is an expression, and it's the only expression in this function,
161-
the value will be the result of the `if`.
198+
The previous definition without `return` may look a bit strange if you haven’t
199+
worked in an expression-based language before, but it becomes intuitive over
200+
time.
162201

163202
## Diverging functions
164203

165-
Rust has some special syntax for 'diverging functions', which are functions that
204+
Rust has some special syntax for diverging functions, which are functions that
166205
do not return:
167206

168207
```
@@ -171,23 +210,18 @@ fn diverges() -> ! {
171210
}
172211
```
173212

174-
`panic!` is a macro, similar to `println!()` that we've already seen. Unlike
213+
`panic!` is a macro, similar to `println!()` that weve already seen. Unlike
175214
`println!()`, `panic!()` causes the current thread of execution to crash with
176215
the given message.
177216

178217
Because this function will cause a crash, it will never return, and so it has
179-
the type '`!`', which is read "diverges." A diverging function can be used
218+
the type `!`, which is read diverges’. A diverging function can be used
180219
as any type:
181220

182221
```should_panic
183222
# fn diverges() -> ! {
184223
# panic!("This function never returns!");
185224
# }
186-
187225
let x: i32 = diverges();
188226
let x: String = diverges();
189227
```
190-
191-
We don't have a good use for diverging functions yet, because they're used in
192-
conjunction with other Rust features. But when you see `-> !` later, you'll
193-
know what it's called.

src/doc/trpl/structs.md

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
% Structs
22

3-
A struct is another form of a *record type*, just like a tuple. There's a
4-
difference: structs give each element that they contain a name, called a
5-
*field* or a *member*. Check it out:
3+
Structs are a way of creating more complex datatypes. For example, if we were
4+
doing calculations involving coordinates in 2D space, we would need both an `x`
5+
and a `y` value:
6+
7+
```rust
8+
let origin_x = 0;
9+
let origin_y = 0;
10+
```
11+
12+
A struct lets us combine these two into a single, unified datatype:
613

714
```rust
815
struct Point {
@@ -17,7 +24,7 @@ fn main() {
1724
}
1825
```
1926

20-
There's a lot going on here, so let's break it down. We declare a struct with
27+
Theres a lot going on here, so lets break it down. We declare a struct with
2128
the `struct` keyword, and then with a name. By convention, structs begin with a
2229
capital letter and are also camel cased: `PointInSpace`, not `Point_In_Space`.
2330

@@ -31,7 +38,7 @@ notation: `origin.x`.
3138
The values in structs are immutable by default, like other bindings in Rust.
3239
Use `mut` to make them mutable:
3340

34-
```{rust}
41+
```rust
3542
struct Point {
3643
x: i32,
3744
y: i32,
@@ -47,3 +54,36 @@ fn main() {
4754
```
4855

4956
This will print `The point is at (5, 0)`.
57+
58+
Rust does not support field mutability at the language level, so you cannot
59+
write something like this:
60+
61+
```rust,ignore
62+
struct Point {
63+
mut x: i32,
64+
y: i32,
65+
}
66+
```
67+
68+
Mutability is a property of the binding, not of the structure itself. If you’re
69+
used to field-level mutability, this may seem strange at first, but it
70+
significantly simplifies things. It even lets you make things mutable for a short
71+
time only:
72+
73+
74+
```rust,ignore
75+
struct Point {
76+
x: i32,
77+
y: i32,
78+
}
79+
80+
fn main() {
81+
let mut point = Point { x: 0, y: 0 };
82+
83+
point.x = 5;
84+
85+
let point = point; // this new binding can’t change now
86+
87+
point.y = 6; // this causes an error
88+
}
89+
```

0 commit comments

Comments
 (0)