mirror of
https://github.com/notohh/rustlings.git
synced 2024-11-22 22:02:22 -05:00
Merge branch 'main' into comment_cleanup
This commit is contained in:
commit
b44472b237
8 changed files with 161 additions and 90 deletions
|
@ -2136,6 +2136,60 @@
|
||||||
"contributions": [
|
"contributions": [
|
||||||
"content"
|
"content"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "proofconstruction",
|
||||||
|
"name": "proofconstruction",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/74747193?v=4",
|
||||||
|
"profile": "https://github.com/proofconstruction",
|
||||||
|
"contributions": [
|
||||||
|
"infra"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "IVIURRAY",
|
||||||
|
"name": "IVIURRAY",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/16007179?v=4",
|
||||||
|
"profile": "https://www.youtube.com/channel/UCQCjA6qUutAtWqkCA4Z36CQ",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "b-apperlo",
|
||||||
|
"name": "Bert Apperlo",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/91734527?v=4",
|
||||||
|
"profile": "https://github.com/b-apperlo",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "FWDekker",
|
||||||
|
"name": "Florine W. Dekker",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/13442533?v=4",
|
||||||
|
"profile": "https://fwdekker.com/",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "luhem7",
|
||||||
|
"name": "Mehul Gangavelli",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/4008215?v=4",
|
||||||
|
"profile": "https://github.com/luhem7",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "Frosthage",
|
||||||
|
"name": "Mikael Frosthage",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/14823314?v=4",
|
||||||
|
"profile": "https://github.com/Frosthage",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"contributorsPerLine": 8,
|
"contributorsPerLine": 8,
|
||||||
|
@ -2144,5 +2198,6 @@
|
||||||
"repoType": "github",
|
"repoType": "github",
|
||||||
"repoHost": "https://github.com",
|
"repoHost": "https://github.com",
|
||||||
"skipCi": true,
|
"skipCi": true,
|
||||||
"commitConvention": "angular"
|
"commitConvention": "angular",
|
||||||
|
"commitType": "docs"
|
||||||
}
|
}
|
||||||
|
|
2
.github/workflows/rust.yml
vendored
2
.github/workflows/rust.yml
vendored
|
@ -14,6 +14,8 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
- name: Fetch & maybe update Cargo.lock
|
||||||
|
run: cargo fetch --locked
|
||||||
- name: Build
|
- name: Build
|
||||||
run: cargo build --verbose
|
run: cargo build --verbose
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
|
|
|
@ -303,6 +303,12 @@ authors.
|
||||||
<tr>
|
<tr>
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/b1ue64"><img src="https://avatars.githubusercontent.com/u/77976308?v=4?s=100" width="100px;" alt="b1ue64"/><br /><sub><b>b1ue64</b></sub></a><br /><a href="#content-b1ue64" title="Content">🖋</a></td>
|
<td align="center" valign="top" width="12.5%"><a href="https://github.com/b1ue64"><img src="https://avatars.githubusercontent.com/u/77976308?v=4?s=100" width="100px;" alt="b1ue64"/><br /><sub><b>b1ue64</b></sub></a><br /><a href="#content-b1ue64" title="Content">🖋</a></td>
|
||||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/lazywalker"><img src="https://avatars.githubusercontent.com/u/53956?v=4?s=100" width="100px;" alt="lazywalker"/><br /><sub><b>lazywalker</b></sub></a><br /><a href="#content-lazywalker" title="Content">🖋</a></td>
|
<td align="center" valign="top" width="12.5%"><a href="https://github.com/lazywalker"><img src="https://avatars.githubusercontent.com/u/53956?v=4?s=100" width="100px;" alt="lazywalker"/><br /><sub><b>lazywalker</b></sub></a><br /><a href="#content-lazywalker" title="Content">🖋</a></td>
|
||||||
|
<td align="center" valign="top" width="12.5%"><a href="https://github.com/proofconstruction"><img src="https://avatars.githubusercontent.com/u/74747193?v=4?s=100" width="100px;" alt="proofconstruction"/><br /><sub><b>proofconstruction</b></sub></a><br /><a href="#infra-proofconstruction" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
|
||||||
|
<td align="center" valign="top" width="12.5%"><a href="https://www.youtube.com/channel/UCQCjA6qUutAtWqkCA4Z36CQ"><img src="https://avatars.githubusercontent.com/u/16007179?v=4?s=100" width="100px;" alt="IVIURRAY"/><br /><sub><b>IVIURRAY</b></sub></a><br /><a href="#content-IVIURRAY" title="Content">🖋</a></td>
|
||||||
|
<td align="center" valign="top" width="12.5%"><a href="https://github.com/b-apperlo"><img src="https://avatars.githubusercontent.com/u/91734527?v=4?s=100" width="100px;" alt="Bert Apperlo"/><br /><sub><b>Bert Apperlo</b></sub></a><br /><a href="#content-b-apperlo" title="Content">🖋</a></td>
|
||||||
|
<td align="center" valign="top" width="12.5%"><a href="https://fwdekker.com/"><img src="https://avatars.githubusercontent.com/u/13442533?v=4?s=100" width="100px;" alt="Florine W. Dekker"/><br /><sub><b>Florine W. Dekker</b></sub></a><br /><a href="#content-FWDekker" title="Content">🖋</a></td>
|
||||||
|
<td align="center" valign="top" width="12.5%"><a href="https://github.com/luhem7"><img src="https://avatars.githubusercontent.com/u/4008215?v=4?s=100" width="100px;" alt="Mehul Gangavelli"/><br /><sub><b>Mehul Gangavelli</b></sub></a><br /><a href="#content-luhem7" title="Content">🖋</a></td>
|
||||||
|
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Frosthage"><img src="https://avatars.githubusercontent.com/u/14823314?v=4?s=100" width="100px;" alt="Mikael Frosthage"/><br /><sub><b>Mikael Frosthage</b></sub></a><br /><a href="#content-Frosthage" title="Content">🖋</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -20,6 +20,7 @@ struct State {
|
||||||
color: (u8, u8, u8),
|
color: (u8, u8, u8),
|
||||||
position: Point,
|
position: Point,
|
||||||
quit: bool,
|
quit: bool,
|
||||||
|
message: String
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
|
@ -31,9 +32,7 @@ impl State {
|
||||||
self.quit = true;
|
self.quit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn echo(&self, s: String) {
|
fn echo(&mut self, s: String) { self.message = s }
|
||||||
println!("{}", s);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn move_position(&mut self, p: Point) {
|
fn move_position(&mut self, p: Point) {
|
||||||
self.position = p;
|
self.position = p;
|
||||||
|
@ -57,6 +56,7 @@ mod tests {
|
||||||
quit: false,
|
quit: false,
|
||||||
position: Point { x: 0, y: 0 },
|
position: Point { x: 0, y: 0 },
|
||||||
color: (0, 0, 0),
|
color: (0, 0, 0),
|
||||||
|
message: "hello world".to_string(),
|
||||||
};
|
};
|
||||||
state.process(Message::ChangeColor(255, 0, 255));
|
state.process(Message::ChangeColor(255, 0, 255));
|
||||||
state.process(Message::Echo(String::from("hello world")));
|
state.process(Message::Echo(String::from("hello world")));
|
||||||
|
@ -67,5 +67,6 @@ mod tests {
|
||||||
assert_eq!(state.position.x, 10);
|
assert_eq!(state.position.x, 10);
|
||||||
assert_eq!(state.position.y, 15);
|
assert_eq!(state.position.y, 15);
|
||||||
assert_eq!(state.quit, true);
|
assert_eq!(state.quit, true);
|
||||||
|
assert_eq!(state.message, "hello world");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,4 +81,13 @@ mod tests {
|
||||||
let count = basket.values().sum::<u32>();
|
let count = basket.values().sum::<u32>();
|
||||||
assert!(count > 11);
|
assert!(count > 11);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn all_fruit_types_in_basket() {
|
||||||
|
let mut basket = get_fruit_basket();
|
||||||
|
fruit_basket(&mut basket);
|
||||||
|
for amount in basket.values() {
|
||||||
|
assert_ne!(amount, &0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,9 +18,8 @@
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
// A structure to store team name and its goal details.
|
// A structure to store the goal details of a team.
|
||||||
struct Team {
|
struct Team {
|
||||||
name: String,
|
|
||||||
goals_scored: u8,
|
goals_scored: u8,
|
||||||
goals_conceded: u8,
|
goals_conceded: u8,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
// move_semantics2.rs
|
// move_semantics2.rs
|
||||||
//
|
//
|
||||||
// Expected output:
|
// Expected output:
|
||||||
// vec0 has length 3 content `[22, 44, 66]`
|
// vec0 has length 3, with contents `[22, 44, 66]`
|
||||||
// vec1 has length 4 content `[22, 44, 66, 88]`
|
// vec1 has length 4, with contents `[22, 44, 66, 88]`
|
||||||
//
|
//
|
||||||
// Execute `rustlings hint move_semantics2` or use the `hint` watch subcommand
|
// Execute `rustlings hint move_semantics2` or use the `hint` watch subcommand
|
||||||
// for a hint.
|
// for a hint.
|
||||||
|
@ -12,15 +12,13 @@
|
||||||
fn main() {
|
fn main() {
|
||||||
let vec0 = Vec::new();
|
let vec0 = Vec::new();
|
||||||
|
|
||||||
// Do not move the following line!
|
|
||||||
let mut vec1 = fill_vec(vec0);
|
let mut vec1 = fill_vec(vec0);
|
||||||
|
|
||||||
// Do not change the following line!
|
println!("{} has length {}, with contents: `{:?}`", "vec0", vec0.len(), vec0);
|
||||||
println!("{} has length {} content `{:?}`", "vec0", vec0.len(), vec0);
|
|
||||||
|
|
||||||
vec1.push(88);
|
vec1.push(88);
|
||||||
|
|
||||||
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
|
println!("{} has length {}, with contents `{:?}`", "vec1", vec1.len(), vec1);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
|
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
|
||||||
|
|
157
info.toml
157
info.toml
|
@ -260,8 +260,8 @@ name = "vecs2"
|
||||||
path = "exercises/vecs/vecs2.rs"
|
path = "exercises/vecs/vecs2.rs"
|
||||||
mode = "test"
|
mode = "test"
|
||||||
hint = """
|
hint = """
|
||||||
Hint 1: `i` is each element from the Vec as they are being iterated. Can you try
|
Hint 1: `element` is each element from the Vec as they are being iterated. Can you
|
||||||
multiplying this?
|
try multiplying this?
|
||||||
|
|
||||||
Hint 2: For the first function, there's a way to directly access the numbers stored
|
Hint 2: For the first function, there's a way to directly access the numbers stored
|
||||||
in the Vec, using the * dereference operator. You can both access and write to the
|
in the Vec, using the * dereference operator. You can both access and write to the
|
||||||
|
@ -287,23 +287,24 @@ Also: Try accessing `vec0` after having called `fill_vec()`. See what happens!""
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
name = "move_semantics2"
|
name = "move_semantics2"
|
||||||
path = "exercises/move_semantics/move_semantics2.rs"
|
path = "exercises/move_semantics/move_semantics2.rs"
|
||||||
mode = "compile"
|
mode = "test"
|
||||||
hint = """
|
hint = """
|
||||||
So, `vec0` is passed into the `fill_vec` function as an argument. In Rust,
|
When running this exercise for the first time, you'll notice an error about
|
||||||
when an argument is passed to a function and it's not explicitly returned,
|
"borrow of moved value". In Rust, when an argument is passed to a function and
|
||||||
you can't use the original variable anymore. We call this "moving" a variable.
|
it's not explicitly returned, you can't use the original variable anymore.
|
||||||
Variables that are moved into a function (or block scope) and aren't explicitly
|
We call this "moving" a variable. When we pass `vec0` into `fill_vec`, it's being
|
||||||
returned get "dropped" at the end of that function. This is also what happens here.
|
"moved" into `vec1`, meaning we can't access `vec0` anymore after the fact.
|
||||||
There's a few ways to fix this, try them all if you want:
|
Rust provides a couple of different ways to mitigate this issue, feel free to try them all:
|
||||||
1. Make another, separate version of the data that's in `vec0` and pass that
|
1. You could make another, separate version of the data that's in `vec0` and pass that
|
||||||
to `fill_vec` instead.
|
to `fill_vec` instead.
|
||||||
2. Make `fill_vec` borrow its argument instead of taking ownership of it,
|
2. Make `fill_vec` borrow its argument instead of taking ownership of it,
|
||||||
and then copy the data within the function in order to return an owned
|
and then copy the data within the function (`vec.clone()`) in order to return an owned
|
||||||
`Vec<i32>`
|
`Vec<i32>`.
|
||||||
3. Make `fill_vec` *mutably* borrow a reference to its argument (which will need to be
|
3. Or, you could make `fill_vec` *mutably* borrow a reference to its argument (which will need to be
|
||||||
mutable), modify it directly, then not return anything. Then you can get rid
|
mutable), modify it directly, then not return anything. This means that `vec0` will change over the
|
||||||
of `vec1` entirely -- note that this will change what gets printed by the
|
course of the function, and makes `vec1` redundant (make sure to change the parameters of the `println!`
|
||||||
first `println!`"""
|
statements if you go this route)
|
||||||
|
"""
|
||||||
|
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
name = "move_semantics3"
|
name = "move_semantics3"
|
||||||
|
@ -905,67 +906,6 @@ The fold method can be useful in the count_collection_iterator function.
|
||||||
For a further challenge, consult the documentation for Iterator to find
|
For a further challenge, consult the documentation for Iterator to find
|
||||||
a different method that could make your code more compact than using fold."""
|
a different method that could make your code more compact than using fold."""
|
||||||
|
|
||||||
# THREADS
|
|
||||||
|
|
||||||
[[exercises]]
|
|
||||||
name = "threads1"
|
|
||||||
path = "exercises/threads/threads1.rs"
|
|
||||||
mode = "compile"
|
|
||||||
hint = """
|
|
||||||
`JoinHandle` is a struct that is returned from a spawned thread:
|
|
||||||
https://doc.rust-lang.org/std/thread/fn.spawn.html
|
|
||||||
|
|
||||||
A challenge with multi-threaded applications is that the main thread can
|
|
||||||
finish before the spawned threads are completed.
|
|
||||||
https://doc.rust-lang.org/book/ch16-01-threads.html#waiting-for-all-threads-to-finish-using-join-handles
|
|
||||||
|
|
||||||
Use the JoinHandles to wait for each thread to finish and collect their results.
|
|
||||||
https://doc.rust-lang.org/std/thread/struct.JoinHandle.html
|
|
||||||
"""
|
|
||||||
|
|
||||||
[[exercises]]
|
|
||||||
name = "threads2"
|
|
||||||
path = "exercises/threads/threads2.rs"
|
|
||||||
mode = "compile"
|
|
||||||
hint = """
|
|
||||||
`Arc` is an Atomic Reference Counted pointer that allows safe, shared access
|
|
||||||
to **immutable** data. But we want to *change* the number of `jobs_completed`
|
|
||||||
so we'll need to also use another type that will only allow one thread to
|
|
||||||
mutate the data at a time. Take a look at this section of the book:
|
|
||||||
https://doc.rust-lang.org/book/ch16-03-shared-state.html#atomic-reference-counting-with-arct
|
|
||||||
and keep reading if you'd like more hints :)
|
|
||||||
|
|
||||||
|
|
||||||
Do you now have an `Arc` `Mutex` `JobStatus` at the beginning of main? Like:
|
|
||||||
`let status = Arc::new(Mutex::new(JobStatus { jobs_completed: 0 }));`
|
|
||||||
Similar to the code in the example in the book that happens after the text
|
|
||||||
that says "We can use Arc<T> to fix this.". If not, give that a try! If you
|
|
||||||
do and would like more hints, keep reading!!
|
|
||||||
|
|
||||||
|
|
||||||
Make sure neither of your threads are holding onto the lock of the mutex
|
|
||||||
while they are sleeping, since this will prevent the other thread from
|
|
||||||
being allowed to get the lock. Locks are automatically released when
|
|
||||||
they go out of scope.
|
|
||||||
|
|
||||||
If you've learned from the sample solutions, I encourage you to come
|
|
||||||
back to this exercise and try it again in a few days to reinforce
|
|
||||||
what you've learned :)"""
|
|
||||||
|
|
||||||
[[exercises]]
|
|
||||||
name = "threads3"
|
|
||||||
path = "exercises/threads/threads3.rs"
|
|
||||||
mode = "compile"
|
|
||||||
hint = """
|
|
||||||
An alternate way to handle concurrency between threads is to use
|
|
||||||
a mpsc (multiple producer, single consumer) channel to communicate.
|
|
||||||
With both a sending end and a receiving end, it's possible to
|
|
||||||
send values in one thread and receive them in another.
|
|
||||||
Multiple producers are possible by using clone() to create a duplicate
|
|
||||||
of the original sending end.
|
|
||||||
See https://doc.rust-lang.org/book/ch16-02-message-passing.html for more info.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# SMART POINTERS
|
# SMART POINTERS
|
||||||
|
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
|
@ -1028,6 +968,67 @@ Check out https://doc.rust-lang.org/std/borrow/enum.Cow.html for documentation
|
||||||
on the `Cow` type.
|
on the `Cow` type.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# THREADS
|
||||||
|
|
||||||
|
[[exercises]]
|
||||||
|
name = "threads1"
|
||||||
|
path = "exercises/threads/threads1.rs"
|
||||||
|
mode = "compile"
|
||||||
|
hint = """
|
||||||
|
`JoinHandle` is a struct that is returned from a spawned thread:
|
||||||
|
https://doc.rust-lang.org/std/thread/fn.spawn.html
|
||||||
|
|
||||||
|
A challenge with multi-threaded applications is that the main thread can
|
||||||
|
finish before the spawned threads are completed.
|
||||||
|
https://doc.rust-lang.org/book/ch16-01-threads.html#waiting-for-all-threads-to-finish-using-join-handles
|
||||||
|
|
||||||
|
Use the JoinHandles to wait for each thread to finish and collect their results.
|
||||||
|
https://doc.rust-lang.org/std/thread/struct.JoinHandle.html
|
||||||
|
"""
|
||||||
|
|
||||||
|
[[exercises]]
|
||||||
|
name = "threads2"
|
||||||
|
path = "exercises/threads/threads2.rs"
|
||||||
|
mode = "compile"
|
||||||
|
hint = """
|
||||||
|
`Arc` is an Atomic Reference Counted pointer that allows safe, shared access
|
||||||
|
to **immutable** data. But we want to *change* the number of `jobs_completed`
|
||||||
|
so we'll need to also use another type that will only allow one thread to
|
||||||
|
mutate the data at a time. Take a look at this section of the book:
|
||||||
|
https://doc.rust-lang.org/book/ch16-03-shared-state.html#atomic-reference-counting-with-arct
|
||||||
|
and keep reading if you'd like more hints :)
|
||||||
|
|
||||||
|
|
||||||
|
Do you now have an `Arc` `Mutex` `JobStatus` at the beginning of main? Like:
|
||||||
|
`let status = Arc::new(Mutex::new(JobStatus { jobs_completed: 0 }));`
|
||||||
|
Similar to the code in the example in the book that happens after the text
|
||||||
|
that says "We can use Arc<T> to fix this.". If not, give that a try! If you
|
||||||
|
do and would like more hints, keep reading!!
|
||||||
|
|
||||||
|
|
||||||
|
Make sure neither of your threads are holding onto the lock of the mutex
|
||||||
|
while they are sleeping, since this will prevent the other thread from
|
||||||
|
being allowed to get the lock. Locks are automatically released when
|
||||||
|
they go out of scope.
|
||||||
|
|
||||||
|
If you've learned from the sample solutions, I encourage you to come
|
||||||
|
back to this exercise and try it again in a few days to reinforce
|
||||||
|
what you've learned :)"""
|
||||||
|
|
||||||
|
[[exercises]]
|
||||||
|
name = "threads3"
|
||||||
|
path = "exercises/threads/threads3.rs"
|
||||||
|
mode = "compile"
|
||||||
|
hint = """
|
||||||
|
An alternate way to handle concurrency between threads is to use
|
||||||
|
a mpsc (multiple producer, single consumer) channel to communicate.
|
||||||
|
With both a sending end and a receiving end, it's possible to
|
||||||
|
send values in one thread and receive them in another.
|
||||||
|
Multiple producers are possible by using clone() to create a duplicate
|
||||||
|
of the original sending end.
|
||||||
|
See https://doc.rust-lang.org/book/ch16-02-message-passing.html for more info.
|
||||||
|
"""
|
||||||
|
|
||||||
# MACROS
|
# MACROS
|
||||||
|
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
|
@ -1170,4 +1171,4 @@ name = "as_ref_mut"
|
||||||
path = "exercises/conversions/as_ref_mut.rs"
|
path = "exercises/conversions/as_ref_mut.rs"
|
||||||
mode = "test"
|
mode = "test"
|
||||||
hint = """
|
hint = """
|
||||||
Add AsRef<str> as a trait bound to the functions."""
|
Add AsRef<str> or AsMut<u32> as a trait bound to the functions."""
|
||||||
|
|
Loading…
Reference in a new issue