You've already forked comprehensive-rust
mirror of
https://github.com/google/comprehensive-rust.git
synced 2025-12-23 06:56:25 +02:00
Comprehensive Rust v2 (#1073)
I've taken some work by @fw-immunant and others on the new organization of the course and condensed it into a form amenable to a text editor and some computational analysis. You can see the inputs in `course.py` but the interesting bits are the output: `outline.md` and `slides.md`. The idea is to break the course into more, smaller segments with exercises at the ends and breaks in between. So `outline.md` lists the segments, their duration, and sums those durations up per-day. It shows we're about an hour too long right now! There are more details of the segments in `slides.md`, or you can see mostly the same stuff in `course.py`. This now contains all of the content from the v1 course, ensuring both that we've covered everything and that we'll have somewhere to redirect every page. Fixes #1082. Fixes #1465. --------- Co-authored-by: Nicole LeGare <dlegare.1001@gmail.com> Co-authored-by: Martin Geisler <mgeisler@google.com>
This commit is contained in:
committed by
GitHub
parent
ea204774b6
commit
6d19292f16
9
src/references/Cargo.toml
Normal file
9
src/references/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "references"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
[[bin]]
|
||||
name = "references"
|
||||
path = "exercise.rs"
|
||||
34
src/references/exclusive.md
Normal file
34
src/references/exclusive.md
Normal file
@@ -0,0 +1,34 @@
|
||||
---
|
||||
minutes: 10
|
||||
---
|
||||
|
||||
# Exclusive References
|
||||
|
||||
Exclusive references, also known as mutable references, allow changing the value
|
||||
they refer to. They have type `&mut T`.
|
||||
|
||||
<!-- mdbook-xgettext: skip -->
|
||||
```rust,editable
|
||||
fn main() {
|
||||
let mut point = (1, 2);
|
||||
let x_coord = &mut point.0;
|
||||
*x_coord = 20;
|
||||
println!("point: {point:?}");
|
||||
}
|
||||
```
|
||||
|
||||
<details>
|
||||
|
||||
Key points:
|
||||
|
||||
* "Exclusive" means that only this reference can be used to access the value.
|
||||
No other references (shared or exclusive) can exist at the same time, and the
|
||||
referenced value cannot be accessed while the exclusive reference exists. Try
|
||||
making an `&point.0` or changing `point.0` while `x_coord` is alive.
|
||||
|
||||
* Be sure to note the difference between `let mut x_coord: &i32` and `let
|
||||
x_coord: &mut i32`. The first one represents a shared reference which can be
|
||||
bound to different values, while the second represents an exclusive reference
|
||||
to a mutable value.
|
||||
|
||||
</details>
|
||||
31
src/references/exercise.md
Normal file
31
src/references/exercise.md
Normal file
@@ -0,0 +1,31 @@
|
||||
---
|
||||
minutes: 30
|
||||
---
|
||||
|
||||
# Exercise: Geometry
|
||||
|
||||
We will create a few utility functions for 3-dimensional geometry, representing
|
||||
a point as `[f64;3]`. It is up to you to determine the function signatures.
|
||||
|
||||
```rust,compile_fail
|
||||
// Calculate the magnitude of a vector by summing the squares of its coordinates
|
||||
// and taking the square root. Use the `sqrt()` method to calculate the square
|
||||
// root, like `v.sqrt()`.
|
||||
|
||||
{{#include exercise.rs:magnitude}}
|
||||
fn magnitude(...) -> f64 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
// Normalize a vector by calculating its magnitude and dividing all of its
|
||||
// coordinates by that magnitude.
|
||||
|
||||
{{#include exercise.rs:normalize}}
|
||||
fn normalize(...) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
// Use the following `main` to test your work.
|
||||
|
||||
{{#include exercise.rs:main}}
|
||||
```
|
||||
45
src/references/exercise.rs
Normal file
45
src/references/exercise.rs
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// ANCHOR: solution
|
||||
/// Calculate the magnitude of the given vector.
|
||||
fn magnitude(vector: &[f64; 3]) -> f64 {
|
||||
let mut mag_squared = 0.0;
|
||||
for coord in vector {
|
||||
mag_squared += coord * coord;
|
||||
}
|
||||
mag_squared.sqrt()
|
||||
}
|
||||
|
||||
/// Change the magnitude of the vector to 1.0 without changing its direction.
|
||||
fn normalize(vector: &mut [f64; 3]) {
|
||||
let mag = magnitude(vector);
|
||||
vector[0] /= mag;
|
||||
vector[1] /= mag;
|
||||
vector[2] /= mag;
|
||||
}
|
||||
|
||||
// ANCHOR: main
|
||||
fn main() {
|
||||
println!(
|
||||
"Magnitude of a unit vector: {}",
|
||||
magnitude(&[0.0, 1.0, 0.0])
|
||||
);
|
||||
|
||||
let mut v = [1.0, 2.0, 9.0];
|
||||
println!("Magnitude of {v:?}: {}", magnitude(&v));
|
||||
normalize(&mut v);
|
||||
println!("Magnitude of {v:?} after normalization: {}", magnitude(&v));
|
||||
}
|
||||
// ANCHOR_END: main
|
||||
70
src/references/shared.md
Normal file
70
src/references/shared.md
Normal file
@@ -0,0 +1,70 @@
|
||||
---
|
||||
minutes: 10
|
||||
---
|
||||
|
||||
# Shared References
|
||||
|
||||
A reference provides a way to access another value without taking responsibility
|
||||
for the value, and is also called "borrowing". Shared references are read-only,
|
||||
and the referenced data cannot change.
|
||||
|
||||
<!-- mdbook-xgettext: skip -->
|
||||
```rust,editable
|
||||
fn main() {
|
||||
let a = 'A';
|
||||
let b = 'B';
|
||||
let mut r: &char = &a;
|
||||
println!("r: {}", *r);
|
||||
r = &b;
|
||||
println!("r: {}", *r);
|
||||
}
|
||||
```
|
||||
|
||||
A shared reference to a type `T` has type `&T`. A reference value is made with the `&`
|
||||
operator. The `*` operator "dereferences" a reference, yielding its value.
|
||||
|
||||
Rust will statically forbid dangling references:
|
||||
|
||||
<!-- mdbook-xgettext: skip -->
|
||||
```rust,editable,compile_fail
|
||||
fn x_axis(x: i32) -> &(i32, i32) {
|
||||
let point = (x, 0);
|
||||
return &point;
|
||||
}
|
||||
```
|
||||
|
||||
<details>
|
||||
|
||||
* A reference is said to "borrow" the value it refers to, and this is a good
|
||||
model for students not familiar with pointers: code can use the reference to
|
||||
access the value, but is still "owned" by the original variable. The course
|
||||
will get into more detail on ownership in day 3.
|
||||
|
||||
* References are implemented as pointers, and a key advantage is that they can
|
||||
be much smaller than the thing they point to. Students familiar with C or C++
|
||||
will recognize references as pointers. Later parts of the course will cover
|
||||
how Rust prevents the memory-safety bugs that come from using raw pointers.
|
||||
|
||||
* Rust does not automatically create references for you - the `&` is always
|
||||
required.
|
||||
|
||||
* Rust will auto-dereference in some cases, in particular when invoking
|
||||
methods (try `r.count_ones()`). There is no need for an `->` operator
|
||||
like in C++.
|
||||
|
||||
* In this example, `r` is mutable so that it can be reassigned (`r = &b`).
|
||||
Note that this re-binds `r`, so that it refers to something else. This is
|
||||
different from C++, where assignment to a reference changes the referenced
|
||||
value.
|
||||
|
||||
* A shared reference does not allow modifying the value it refers to, even if
|
||||
that value was mutable. Try `*r = 'X'`.
|
||||
|
||||
* Rust is tracking the lifetimes of all references to ensure they live long
|
||||
enough. Dangling references cannot occur in safe Rust. `x_axis` would return
|
||||
a reference to `point`, but `point` will be deallocated when the function
|
||||
returns, so this will not compile.
|
||||
|
||||
* We will talk more about borrowing when we get to ownership.
|
||||
|
||||
</details>
|
||||
5
src/references/solution.md
Normal file
5
src/references/solution.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Solution
|
||||
|
||||
```rust,editable
|
||||
{{#include exercise.rs:solution}}
|
||||
```
|
||||
Reference in New Issue
Block a user