Compare commits

...

21 Commits

Author SHA1 Message Date
LukeMathWalker
5ef0a6aa12 Formatting 2024-08-01 15:33:23 +02:00
LukeMathWalker
f882f0416d Change exercise for mutable slices. Closes #26 2024-08-01 15:33:13 +02:00
LukeMathWalker
6029a8fc17 Ensure that overflow checks are active for the copy exercise. Closes #64 2024-08-01 15:14:10 +02:00
LukeMathWalker
056505d89f It's enough for one field to be private. Closes #69 2024-08-01 15:10:50 +02:00
LukeMathWalker
b039a6c5c2 Formatting 2024-08-01 15:09:40 +02:00
LukeMathWalker
3a9c9ea520 Remove reference to cargo new to avoid confusion. Closes #71. 2024-08-01 15:09:24 +02:00
LukeMathWalker
3f4d31148f Add cargo-modules. Closes #101 2024-08-01 14:56:43 +02:00
LukeMathWalker
2f067058ce Fix #104 2024-08-01 14:54:25 +02:00
LukeMathWalker
be5c0e8bae Reword 'static issues. Closes #117 2024-08-01 14:53:53 +02:00
LukeMathWalker
a6056381bd No need to deploy anymore. 2024-07-30 16:13:20 +02:00
code-cp
59833f2a55 Update 06_async_aware_primitives.md (#122)
Fix a typo
2024-07-28 12:46:20 +02:00
Zhang Zihao
9a2086081c Fix a typo (#116) 2024-07-17 08:08:22 +02:00
Jack Moffitt
f272843c61 Remove pub visibility on server() as the argument has a private type. This gets rid of a warning. (#112) 2024-07-07 21:18:43 +02:00
Evgeniy Filimonov
fccad08921 07_threads: 03_leak: Leak vector with Vec::leak, not Box::leak (#107) 2024-06-30 18:23:20 +02:00
Palash Nigam (He/Him)
de45f8adf2 Ch-08 Futures Exercise 02: Fix typo (#106) 2024-06-30 00:18:46 +02:00
LOGI
5660a2f7a8 fix(typo): a module name in comments (#102)
The output of the compiler does not include the module name of the `Ticket` struct and the root module of this exercise is `visibility` rather than `encapsulation` which is the root module of the next exercise.
2024-06-27 11:35:11 +02:00
Saqib Ahmed
491319a6d5 fix: fix a typo (#103) 2024-06-27 11:34:02 +02:00
Jerry Wu
83cf1cad62 Update 11_locks.md (#94)
Suggest removing an extra semicolon.
2024-06-20 10:21:53 +02:00
Ernie Hershey
d8d7e73f1c fix syntax with comma (#89)
Example doesn't compile with a comma here
2024-06-20 10:21:33 +02:00
Onè
468de3c0ac Change test to require impl (#87)
impl std::ops::Add<&SaturatingU16> for SaturatingU16
2024-06-20 10:21:14 +02:00
tomgrbz
c86360f3c4 Remove array/slice syntax from argument &mut str in TODO comment for lowercase func (#99)
Co-authored-by: thomasgrbic <grbic.t@northeastern.edu>
2024-06-20 10:18:55 +02:00
18 changed files with 43 additions and 65 deletions

View File

@@ -39,18 +39,6 @@ jobs:
with:
name: book
path: book/book
# Commit and push all changed files.
# Must only affect files that are listed in "paths-ignore".
- name: Git commit build artifacts
# Only run on main branch push (e.g. pull request merge).
if: github.event_name == 'push'
run: |
git checkout -b deploy
git config --global user.name "Deployer"
git config --global user.email "username@users.noreply.github.com"
git add --force book/book
git commit -m "Render book"
git push --set-upstream --force-with-lease origin deploy
formatter:
runs-on: ubuntu-latest

View File

@@ -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

View File

@@ -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.

View File

@@ -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

View File

@@ -108,7 +108,7 @@ let title = String::from("A title");
We've been primarily using `.into()`, though.\
If you check out the [implementors of `Into`](https://doc.rust-lang.org/std/convert/trait.Into.html#implementors)
you won't find `Into<&str> for String`. What's going on?
you won't find `Into<String> for &str`. What's going on?
`From` and `Into` are **dual traits**.\
In particular, `Into` is implemented for any type that implements `From` using a **blanket implementation**:

View File

@@ -8,7 +8,7 @@ impl Ticket {
match &self.status {
Status::InProgress { assigned_to } => assigned_to,
Status::Done | Status::ToDo => {
panic!("Only `In-Progress` tickets can be assigned to someone"),
panic!("Only `In-Progress` tickets can be assigned to someone")
}
}
}

View File

@@ -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
```

View File

@@ -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.

View File

@@ -27,12 +27,12 @@ run out and crash with an out-of-memory error.
fn oom_trigger() {
loop {
let v: Vec<usize> = Vec::with_capacity(1024);
Box::leak(v);
v.leak();
}
}
```
At the same time, memory leaked via `Box::leak` is not truly forgotten.\
At the same time, memory leaked via `leak` method is not truly forgotten.\
The operating system can map each memory region to the process responsible for it.
When the process exits, the operating system will reclaim that memory.

View File

@@ -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.

View File

@@ -99,7 +99,7 @@ fn main() {
let guard = lock.lock().unwrap();
spawn(move || {
receiver.recv().unwrap();;
receiver.recv().unwrap();
});
// Try to send the guard over the channel
@@ -118,7 +118,7 @@ error[E0277]: `MutexGuard<'_, i32>` cannot be sent between threads safely
| _-----_^
| | |
| | required by a bound introduced by this call
11 | | receiver.recv().unwrap();;
11 | | receiver.recv().unwrap();
12 | | });
| |_^ `MutexGuard<'_, i32>` cannot be sent between threads safely
|

View File

@@ -112,7 +112,7 @@ pub async fn work() {
### `std::thread::spawn` vs `tokio::spawn`
You can think of `tokio::spawn` as the asynchronous sibling of `std::spawn::thread`.
You can think of `tokio::spawn` as the asynchronous sibling of `std::thread::spawn`.
Notice a key difference: with `std::thread::spawn`, you're delegating control to the OS scheduler.
You're not in control of how threads are scheduled.

View File

@@ -52,7 +52,7 @@ Yields to runtime
Tries to acquire lock
```
We have a deadlock. Task B we'll never manage to acquire the lock, because the lock
We have a deadlock. Task B will never manage to acquire the lock, because the lock
is currently held by task A, which has yielded to the runtime before releasing the
lock and won't be scheduled again because the runtime cannot preempt task B.

View File

@@ -48,7 +48,7 @@ mod tests {
// You should be seeing this error when trying to run this exercise:
//
// error[E0616]: field `description` of struct `encapsulation::ticket::Ticket` is private
// error[E0616]: field `description` of struct `Ticket` is private
// |
// | assert_eq!(ticket.description, "A description");
// | ^^^^^^^^^^^^^^^^^^

View File

@@ -6,11 +6,12 @@ fn test_saturating_u16() {
let b: SaturatingU16 = 5u8.into();
let c: SaturatingU16 = u16::MAX.into();
let d: SaturatingU16 = (&1u16).into();
let e = &c;
assert_eq!(a + b, SaturatingU16::from(15u16));
assert_eq!(a + c, SaturatingU16::from(u16::MAX));
assert_eq!(a + d, SaturatingU16::from(11u16));
assert_eq!(a + a, 20u16);
assert_eq!(a + 5u16, 15u16);
assert_eq!(a + &u16::MAX, SaturatingU16::from(u16::MAX));
assert_eq!(a + e, SaturatingU16::from(u16::MAX));
}

View File

@@ -43,7 +43,7 @@ mod tests {
}
#[test]
fn thirthieth() {
fn thirtieth() {
assert_eq!(fibonacci(30), 832040);
}
}

View File

@@ -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]);
}
}

View File

@@ -38,7 +38,7 @@ enum Command {
},
}
pub fn server(receiver: Receiver<Command>) {
fn server(receiver: Receiver<Command>) {
let mut store = TicketStore::new();
loop {
match receiver.recv() {