You've already forked comprehensive-rust
mirror of
https://github.com/google/comprehensive-rust.git
synced 2025-12-23 06:56:25 +02:00
Publish Comprehensive Rust 🦀
This commit is contained in:
36
src/control-flow/blocks.md
Normal file
36
src/control-flow/blocks.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# Blocks
|
||||
|
||||
A block in Rust has a value and a type: the value is the last expression of the
|
||||
block:
|
||||
|
||||
```rust,editable
|
||||
fn main() {
|
||||
let x = {
|
||||
let y = 10;
|
||||
println!("y: {y}");
|
||||
let z = {
|
||||
let w = {
|
||||
3 + 4
|
||||
};
|
||||
println!("w: {w}");
|
||||
y * w
|
||||
};
|
||||
println!("z: {z}");
|
||||
z - y
|
||||
};
|
||||
println!("x: {x}");
|
||||
}
|
||||
```
|
||||
|
||||
The same rule is used for functions: the value of the function body is the
|
||||
return value:
|
||||
|
||||
```rust,editable
|
||||
fn double(x: i32) -> i32 {
|
||||
x + x
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("doubled: {}", double(7));
|
||||
}
|
||||
```
|
||||
25
src/control-flow/break-continue.md
Normal file
25
src/control-flow/break-continue.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# `break` and `continue`
|
||||
|
||||
If you want to exit a loop early, use `break`, if you want to immediately start
|
||||
the next iteration use `continue`. Both `continue` and `break` can optionally
|
||||
take a label argument which is used to break out of nested loops:
|
||||
|
||||
```rust,editable
|
||||
fn main() {
|
||||
let v = vec![10, 20, 30];
|
||||
let mut iter = v.into_iter();
|
||||
'outer: while let Some(x) = iter.next() {
|
||||
println!("x: {x}");
|
||||
let mut i = 0;
|
||||
while i < x {
|
||||
println!("x: {x}, i: {i}");
|
||||
i += 1;
|
||||
if i == 3 {
|
||||
break 'outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In this case we break the outer loop after 3 iterations of the inner loop.
|
||||
16
src/control-flow/for-expressions.md
Normal file
16
src/control-flow/for-expressions.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# `for` expressions
|
||||
|
||||
The `for` expression is closely related to the `while let` expression. It will
|
||||
automatically call `into_iter()` on the expression and then iterate over it:
|
||||
|
||||
```rust,editable
|
||||
fn main() {
|
||||
let v = vec![10, 20, 30];
|
||||
|
||||
for x in v {
|
||||
println!("x: {x}");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can use `break` and `continue` here as usual.
|
||||
27
src/control-flow/if-expressions.md
Normal file
27
src/control-flow/if-expressions.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# `if` expressions
|
||||
|
||||
You use `if` very similarly to how you would in other languages:
|
||||
|
||||
```rust,editable
|
||||
fn main() {
|
||||
let mut x = 10;
|
||||
if x % 2 == 0 {
|
||||
x = x / 2;
|
||||
} else {
|
||||
x = 3 * x + 1;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In addition, you can use it as an expression. This does the same as above:
|
||||
|
||||
```rust,editable
|
||||
fn main() {
|
||||
let mut x = 10;
|
||||
x = if x % 2 == 0 {
|
||||
x / 2
|
||||
} else {
|
||||
3 * x + 1
|
||||
};
|
||||
}
|
||||
```
|
||||
17
src/control-flow/if-let-expressions.md
Normal file
17
src/control-flow/if-let-expressions.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# `if let` expressions
|
||||
|
||||
If you want to match a value against a pattern, you can use `if let`:
|
||||
|
||||
```rust,editable
|
||||
fn main() {
|
||||
let arg = std::env::args().next();
|
||||
if let Some(value) = arg {
|
||||
println!("Program name: {value}");
|
||||
} else {
|
||||
println!("Missing name?");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
See [pattern matching](../pattern-matching.md) for more details on patterns in
|
||||
Rust.
|
||||
21
src/control-flow/loop-expressions.md
Normal file
21
src/control-flow/loop-expressions.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# `loop` expressions
|
||||
|
||||
Finally, there is a `loop` keyword which creates an endless loop. Here you must
|
||||
either `break` or `return` to stop the loop:
|
||||
|
||||
```rust,editable
|
||||
fn main() {
|
||||
let mut x = 10;
|
||||
loop {
|
||||
x = if x % 2 == 0 {
|
||||
x / 2
|
||||
} else {
|
||||
3 * x + 1
|
||||
};
|
||||
if x == 1 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
println!("Final x: {x}");
|
||||
}
|
||||
```
|
||||
23
src/control-flow/match-expressions.md
Normal file
23
src/control-flow/match-expressions.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# `match` expressions
|
||||
|
||||
The `match` keyword is used to match a value against one or more patterns. In
|
||||
that sense, it works like a series of `if let` expressions:
|
||||
|
||||
```rust,editable
|
||||
fn main() {
|
||||
match std::env::args().next().as_deref() {
|
||||
Some("cat") => println!("Will do cat things"),
|
||||
Some("ls") => println!("Will ls some files"),
|
||||
Some("mv") => println!("Let's move some files"),
|
||||
Some("rm") => println!("Uh, dangerous!"),
|
||||
None => println!("Hmm, no program name?"),
|
||||
_ => println!("Unknown program name!"),
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Like `if let`, each match arm must have the same type. The type is the last
|
||||
expression of the block, if any. In the example above, the type is `()`.
|
||||
|
||||
See [pattern matching](../pattern-matching.md) for more details on patterns in
|
||||
Rust.
|
||||
18
src/control-flow/while-expressions.md
Normal file
18
src/control-flow/while-expressions.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# `while` expressions
|
||||
|
||||
The `while` keyword works very similar to other languages:
|
||||
|
||||
```rust,editable
|
||||
fn main() {
|
||||
let mut x = 10;
|
||||
while x != 1 {
|
||||
x = if x % 2 == 0 {
|
||||
x / 2
|
||||
} else {
|
||||
3 * x + 1
|
||||
};
|
||||
}
|
||||
println!("Final x: {x}");
|
||||
}
|
||||
```
|
||||
|
||||
22
src/control-flow/while-let-expressions.md
Normal file
22
src/control-flow/while-let-expressions.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# `while let` expressions
|
||||
|
||||
Like with `if`, there is a `while let` variant which repeatedly tests a value
|
||||
against a pattern:
|
||||
|
||||
```rust,editable
|
||||
fn main() {
|
||||
let v = vec![10, 20, 30];
|
||||
let mut iter = v.into_iter();
|
||||
|
||||
while let Some(x) = iter.next() {
|
||||
println!("x: {x}");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Here the iterator returned by `v.iter()` will return a `Option<i32>` on every
|
||||
call to `next()`. It returns `Some(x)` until it is done, after which it will
|
||||
return `None`. The `while let` lets us keep iterating through all items.
|
||||
|
||||
See [pattern matching](../pattern-matching.md) for more details on patterns in
|
||||
Rust.
|
||||
Reference in New Issue
Block a user