mirror of
https://github.com/google/comprehensive-rust.git
synced 2025-04-24 16:42:36 +02:00
More fixes and additions to Day1 Morning (#269)
* Corrections around slices and string slices, also slight improvements to the language. * Explained some of the confusing details in the functions example. * Added a speaker note (hinting at `Into` as a complement to generics). * Exclude the clarification code snippet from build testing. * Update functions-interlude.md Do not mention explicit section numbers as they may change.
This commit is contained in:
parent
b064642b02
commit
10ca7b1b2d
@ -21,3 +21,11 @@ fn main() {
|
|||||||
println!("cash prize: {}", pick_one(500, 1000));
|
println!("cash prize: {}", pick_one(500, 1000));
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<details>
|
||||||
|
|
||||||
|
* When using generics, the standard library's `Into<T>` can provide a kind of limited
|
||||||
|
polymorphism on argument types. We will see more details in a later section.
|
||||||
|
|
||||||
|
</defails>
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ fn is_divisible_by(lhs: u32, rhs: u32) -> bool {
|
|||||||
if rhs == 0 {
|
if rhs == 0 {
|
||||||
return false; // Corner case, early return
|
return false; // Corner case, early return
|
||||||
}
|
}
|
||||||
lhs % rhs == 0 // The last expression is the return value
|
lhs % rhs == 0 // The last expression in a block is the return value
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fizzbuzz(n: u32) -> () { // No return value means returning the unit type `()`
|
fn fizzbuzz(n: u32) -> () { // No return value means returning the unit type `()`
|
||||||
@ -24,8 +24,8 @@ fn fizzbuzz(n: u32) -> () { // No return value means returning the unit type `(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn fizzbuzz_to(n: u32) { // `-> ()` is normally omitted
|
fn fizzbuzz_to(n: u32) { // `-> ()` is normally omitted
|
||||||
for n in 1..=n {
|
for i in 1..=n {
|
||||||
fizzbuzz(n);
|
fizzbuzz(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -34,7 +34,21 @@ fn fizzbuzz_to(n: u32) { // `-> ()` is normally omitted
|
|||||||
|
|
||||||
* We refer in `main` to a function written below. Neither forward declarations nor headers are necessary.
|
* We refer in `main` to a function written below. Neither forward declarations nor headers are necessary.
|
||||||
* Declaration parameters are followed by a type (the reverse of some programming languages), then a return type.
|
* Declaration parameters are followed by a type (the reverse of some programming languages), then a return type.
|
||||||
* The last expression in a function body becomes the return value. Simply omit the `;` at the end of the expression.
|
* The last expression in a function body (or any block) becomes the return value. Simply omit the `;` at the end of the expression.
|
||||||
* Some functions have no return value, and output the 'unit type', `()`. The compiler will infer this if the `-> ()` return type is omitted.
|
* Some functions have no return value, and return the 'unit type', `()`. The compiler will infer this if the `-> ()` return type is omitted.
|
||||||
|
* The range expression in the `for` loop in `fizzbuzz_to()` contains `=n`, which causes it to include the upper bound.
|
||||||
|
* The `match` expression in `fizzbuzz()` is doing a lot of work. It is expanded below to show what is happening.
|
||||||
|
|
||||||
|
(Type annotations added for clarity, but they can be elided.)
|
||||||
|
|
||||||
|
```rust,ignore
|
||||||
|
let by_3: bool = is_divisible_by(n, 3);
|
||||||
|
let by_5: bool = is_divisible_by(n, 5);
|
||||||
|
let by_35: (bool, bool) = (by_3, by_5);
|
||||||
|
match by_35 {
|
||||||
|
// ...
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
@ -19,16 +19,18 @@ fn main() {
|
|||||||
|
|
||||||
* We create a slice by borrowing `a` and specifying the starting and ending indexes in brackets.
|
* We create a slice by borrowing `a` and specifying the starting and ending indexes in brackets.
|
||||||
|
|
||||||
* If the slice starts at index 0, Rust’s range syntax means we can drop the starting index.
|
* If the slice starts at index 0, Rust’s range syntax allows us to drop the starting index, meaning that `&a[0..a.len()]` and `&a[..a.len()]` are identical.
|
||||||
|
|
||||||
* The same is true for the last index, so `&a[2..a.len()]` and `&a[2..]` are equal.
|
* The same is true for the last index, so `&a[2..a.len()]` and `&a[2..]` are identical.
|
||||||
|
|
||||||
* `s` is a reference to a slice of `i32`s. Notice that the type of `s` no longer mentions the array length. This allows us to performing computations on slices of different sizes.
|
* To easily create a slice of the full array, we can therefore use `&a[..]`.
|
||||||
|
|
||||||
|
* `s` is a reference to a slice of `i32`s. Notice that the type of `s` (`&[i32]`) no longer mentions the array length. This allows us to perform computation on slices of different sizes.
|
||||||
|
|
||||||
* Slices always borrow from another object. In this example, `a` has to remain 'alive' so we can take a slice from it.
|
* Slices always borrow from another object. In this example, `a` has to remain 'alive' (in scope) for at least as long as our slice.
|
||||||
|
|
||||||
* The question about modifying `a[3]` can spark an interesting discussion, but the answer is that for memory safety reasons
|
* The question about modifying `a[3]` can spark an interesting discussion, but the answer is that for memory safety reasons
|
||||||
you cannot do it through `a` after you created a slice. But you can read the data from both `a` and `s` safely.
|
you cannot do it through `a` after you created a slice, but you can read the data from both `a` and `s` safely.
|
||||||
More details will be explained in the borrow checker section.
|
More details will be explained in the borrow checker section.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
@ -24,19 +24,21 @@ Rust terminology:
|
|||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
* `&str` introduces a string slice, which is an immutable reference to UTF-8 encoded string data stored in a block of memory. String literals (`”Hello”`), are stored in the program’s binary.
|
* `&str` introduces a string slice, which is an immutable reference to UTF-8 encoded string data
|
||||||
|
stored in a block of memory. String literals (`”Hello”`), are stored in the program’s binary.
|
||||||
|
|
||||||
* Rust’s `String` type is a wrapper around a vector of bytes. As with a `Vec<T>`, it is owned.
|
* Rust’s `String` type is a wrapper around a vector of bytes. As with a `Vec<T>`, it is owned.
|
||||||
|
|
||||||
* As with many other types
|
* As with many other types `String::from()` creates a string from a string literal; `String::new()`
|
||||||
|
creates a new empty string, to which string data can be added using the `push()` and `push_str()` methods.
|
||||||
|
|
||||||
* `String::from` creates a string from a string literal; `String::new` creates a new empty string, to which string data can be added using the `to_string` method.
|
* The `format!()` macro is a convenient way to generate an owned string from dynamic values. It
|
||||||
|
accepts the same format specification as `println!()`.
|
||||||
* The `push_str` method appends a string slice to the string.
|
|
||||||
|
|
||||||
* You can borrow `&str` slices from `String` via `&` and optionally range selection.
|
* You can borrow `&str` slices from `String` via `&` and optionally range selection.
|
||||||
|
|
||||||
* For C++ programmers: think of `&str` as `const char*` from C++, but the one that always points
|
* For C++ programmers: think of `&str` as `const char*` from C++, but the one that always points
|
||||||
to a valid string in memory. Rust `String` is a rough equivalent of `std::string` from C++ (main difference: it can only contain UTF-8 encoded bytes and will never use a small-string optimization).
|
to a valid string in memory. Rust `String` is a rough equivalent of `std::string` from C++
|
||||||
|
(main difference: it can only contain UTF-8 encoded bytes and will never use a small-string optimization).
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user