Compare commits
9 Commits
a6056381bd
...
5ef0a6aa12
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5ef0a6aa12 | ||
|
|
f882f0416d | ||
|
|
6029a8fc17 | ||
|
|
056505d89f | ||
|
|
b039a6c5c2 | ||
|
|
3a9c9ea520 | ||
|
|
3f4d31148f | ||
|
|
2f067058ce | ||
|
|
be5c0e8bae |
@@ -1,3 +1,8 @@
|
||||
[workspace]
|
||||
members = ["exercises/*/*", "helpers/common", "helpers/mdbook-exercise-linker", "helpers/ticket_fields"]
|
||||
resolver = "2"
|
||||
|
||||
# This is needed to guarantee the expected behaviour on that specific exercise,
|
||||
# regardless of the "global" setting for `overflow-checks` on the `dev` profile.
|
||||
[profile.dev.package.copy]
|
||||
overflow-checks = true
|
||||
|
||||
@@ -112,3 +112,10 @@ where each name comes from and potentially introducing name conflicts.\
|
||||
Nonetheless, it can be useful in some cases, like when writing unit tests. You might have noticed
|
||||
that most of our test modules start with a `use super::*;` statement to bring all the items from the parent module
|
||||
(the one being tested) into scope.
|
||||
|
||||
## Visualizing the module tree
|
||||
|
||||
If you're struggling to picture the module tree of your project, you can try using
|
||||
[`cargo-modules`](https://crates.io/crates/cargo-modules) to visualize it!
|
||||
|
||||
Refer to their documentation for installation instructions and usage examples.
|
||||
|
||||
@@ -23,7 +23,7 @@ To enforce stricter rules, we must keep the fields private[^newtype].
|
||||
We can then provide public methods to interact with a `Ticket` instance.
|
||||
Those public methods will have the responsibility of upholding our invariants (e.g. a title must not be empty).
|
||||
|
||||
If all fields are private, it is no longer possible to create a `Ticket` instance directly using the struct
|
||||
If at least one field is private it is no longer possible to create a `Ticket` instance directly using the struct
|
||||
instantiation syntax:
|
||||
|
||||
```rust
|
||||
|
||||
@@ -46,18 +46,3 @@ You can override these defaults by explicitly declaring your targets in the `Car
|
||||
[`cargo`'s documentation](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#cargo-targets) for more details.
|
||||
|
||||
Keep in mind that while a package can contain multiple crates, it can only contain one library crate.
|
||||
|
||||
## Scaffolding a new package
|
||||
|
||||
You can use `cargo` to scaffold a new package:
|
||||
|
||||
```bash
|
||||
cargo new my-binary
|
||||
```
|
||||
|
||||
This will create a new folder, `my-binary`, containing a new Rust package with the same name and a single
|
||||
binary crate inside. If you want to create a library crate instead, you can use the `--lib` flag:
|
||||
|
||||
```bash
|
||||
cargo new my-library --lib
|
||||
```
|
||||
|
||||
@@ -6,7 +6,7 @@ and why we might want to use them.
|
||||
## What is a thread?
|
||||
|
||||
A **thread** is an execution context managed by the underlying operating system.\
|
||||
Each thread has its own stack, instruction pointer, and program counter.
|
||||
Each thread has its own stack and instruction pointer.
|
||||
|
||||
A single **process** can manage multiple threads.
|
||||
These threads share the same memory space, which means they can access the same data.
|
||||
|
||||
@@ -10,9 +10,9 @@ In the non-threaded version of the system, updates were fairly straightforward:
|
||||
|
||||
## Multithreaded updates
|
||||
|
||||
The same strategy won't work in the current multi-threaded version,
|
||||
because the mutable reference would have to be sent over a channel. The borrow checker would
|
||||
stop us, because `&mut Ticket` doesn't satisfy the `'static` lifetime requirement of `SyncSender::send`.
|
||||
The same strategy won't work in the current multithreaded version. The borrow checker would
|
||||
stop us: `SyncSender<&mut Ticket>` isn't `'static` because `&mut Ticket` doesn't satisfy the `'static` lifetime, therefore
|
||||
they can't be captured by the closure that gets passed to `std::thread::spawn`.
|
||||
|
||||
There are a few ways to work around this limitation. We'll explore a few of them in the following exercises.
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// TODO: Define a function named `lowercase` that converts all characters in a string to lowercase,
|
||||
// modifying the input in place.
|
||||
// Does it need to take a `&mut String`? Does a `&mut str` work? Why or why not?
|
||||
// TODO: Define a function named `squared` that raises all `i32`s within a slice to the power of 2.
|
||||
// The slice should be modified in place.
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
@@ -8,29 +7,22 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn empty() {
|
||||
let mut s = String::from("");
|
||||
lowercase(&mut s);
|
||||
assert_eq!(s, "");
|
||||
let mut s = vec![];
|
||||
squared(&mut s);
|
||||
assert_eq!(s, vec![]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn one_char() {
|
||||
let mut s = String::from("A");
|
||||
lowercase(&mut s);
|
||||
assert_eq!(s, "a");
|
||||
fn one() {
|
||||
let mut s = [2];
|
||||
squared(&mut s);
|
||||
assert_eq!(s, [4]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_chars() {
|
||||
let mut s = String::from("Hello, World!");
|
||||
lowercase(&mut s);
|
||||
assert_eq!(s, "hello, world!");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mut_slice() {
|
||||
let mut s = "Hello, World!".to_string();
|
||||
lowercase(s.as_mut_str());
|
||||
assert_eq!(s, "hello, world!");
|
||||
fn multiple() {
|
||||
let mut s = vec![2, 4];
|
||||
squared(&mut s);
|
||||
assert_eq!(s, vec![4, 16]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user