mirror of
https://github.com/rust-lang/rustlings.git
synced 2025-12-26 00:11:49 +02:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7850a73d95 | ||
|
|
1ebb4d25a6 | ||
|
|
b5d440fdc3 | ||
|
|
4700e8a12c | ||
|
|
8753dd6b2e | ||
|
|
f80fbca12e | ||
|
|
d8f4b06c91 | ||
|
|
1955313362 | ||
|
|
95a597eb82 |
@@ -1,5 +1,9 @@
|
||||
## Unreleased
|
||||
|
||||
### Changed
|
||||
|
||||
- `vecs2`: Removed the use of `map` and `collect`, which are only taught later.
|
||||
|
||||
## 6.5.0 (2025-08-21)
|
||||
|
||||
### Added
|
||||
|
||||
@@ -9,26 +9,6 @@ fn vec_loop(input: &[i32]) -> Vec<i32> {
|
||||
output
|
||||
}
|
||||
|
||||
fn vec_map_example(input: &[i32]) -> Vec<i32> {
|
||||
// An example of collecting a vector after mapping.
|
||||
// We map each element of the `input` slice to its value plus 1.
|
||||
// If the input is `[1, 2, 3]`, the output is `[2, 3, 4]`.
|
||||
input.iter().map(|element| element + 1).collect()
|
||||
}
|
||||
|
||||
fn vec_map(input: &[i32]) -> Vec<i32> {
|
||||
// TODO: Here, we also want to multiply each element in the `input` slice
|
||||
// by 2, but with iterator mapping instead of manually pushing into an empty
|
||||
// vector.
|
||||
// See the example in the function `vec_map_example` above.
|
||||
input
|
||||
.iter()
|
||||
.map(|element| {
|
||||
// ???
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// You can optionally experiment here.
|
||||
}
|
||||
@@ -43,18 +23,4 @@ mod tests {
|
||||
let ans = vec_loop(&input);
|
||||
assert_eq!(ans, [4, 8, 12, 16, 20]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec_map_example() {
|
||||
let input = [1, 2, 3];
|
||||
let ans = vec_map_example(&input);
|
||||
assert_eq!(ans, [2, 3, 4]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec_map() {
|
||||
let input = [2, 4, 6, 8, 10];
|
||||
let ans = vec_map(&input);
|
||||
assert_eq!(ans, [4, 8, 12, 16, 20]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// Here are some more easy Clippy fixes so you can see its utility 📎
|
||||
// Here are some more easy Clippy fixes so you can see its utility.
|
||||
// TODO: Fix all the Clippy lints.
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[allow(unused_variables, unused_assignments)]
|
||||
fn main() {
|
||||
let my_option: Option<&str> = None;
|
||||
@@ -11,14 +10,16 @@ fn main() {
|
||||
println!("{}", my_option.unwrap());
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
let my_arr = &[
|
||||
-1, -2, -3
|
||||
-4, -5, -6
|
||||
];
|
||||
println!("My array! Here it is: {my_arr:?}");
|
||||
|
||||
let my_empty_vec = vec![1, 2, 3, 4, 5].resize(0, 5);
|
||||
println!("This Vec is empty, see? {my_empty_vec:?}");
|
||||
let mut my_vec = vec![1, 2, 3, 4, 5];
|
||||
my_vec.resize(0, 5);
|
||||
println!("This Vec is empty, see? {my_vec:?}");
|
||||
|
||||
let mut value_a = 45;
|
||||
let mut value_b = 66;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
| vecs | §8.1 |
|
||||
| move_semantics | §4.1-2 |
|
||||
| structs | §5.1, §5.3 |
|
||||
| enums | §6, §18.3 |
|
||||
| enums | §6, §19.3 |
|
||||
| strings | §8.2 |
|
||||
| modules | §7 |
|
||||
| hashmaps | §8.3 |
|
||||
|
||||
@@ -318,16 +318,7 @@ of the Rust book to learn more."""
|
||||
name = "vecs2"
|
||||
dir = "05_vecs"
|
||||
hint = """
|
||||
In the first function, we create an empty vector and want to push new elements
|
||||
to it.
|
||||
|
||||
In the second function, we map the values of the input and collect them into
|
||||
a vector.
|
||||
|
||||
After you've completed both functions, decide for yourself which approach you
|
||||
like better.
|
||||
|
||||
What do you think is the more commonly used pattern under Rust developers?"""
|
||||
Use the `.push()` method on the vector to push new elements to it."""
|
||||
|
||||
# MOVE SEMANTICS
|
||||
|
||||
|
||||
@@ -8,22 +8,6 @@ fn vec_loop(input: &[i32]) -> Vec<i32> {
|
||||
output
|
||||
}
|
||||
|
||||
fn vec_map_example(input: &[i32]) -> Vec<i32> {
|
||||
// An example of collecting a vector after mapping.
|
||||
// We map each element of the `input` slice to its value plus 1.
|
||||
// If the input is `[1, 2, 3]`, the output is `[2, 3, 4]`.
|
||||
input.iter().map(|element| element + 1).collect()
|
||||
}
|
||||
|
||||
fn vec_map(input: &[i32]) -> Vec<i32> {
|
||||
// We will dive deeper into iterators, but for now, this is all what you
|
||||
// had to do!
|
||||
// Advanced note: This method is more efficient because it automatically
|
||||
// preallocates enough capacity. This can be done manually in `vec_loop`
|
||||
// using `Vec::with_capacity(input.len())` instead of `Vec::new()`.
|
||||
input.iter().map(|element| 2 * element).collect()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// You can optionally experiment here.
|
||||
}
|
||||
@@ -38,18 +22,4 @@ mod tests {
|
||||
let ans = vec_loop(&input);
|
||||
assert_eq!(ans, [4, 8, 12, 16, 20]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec_map_example() {
|
||||
let input = [1, 2, 3];
|
||||
let ans = vec_map_example(&input);
|
||||
assert_eq!(ans, [2, 3, 4]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec_map() {
|
||||
let input = [2, 4, 6, 8, 10];
|
||||
let ans = vec_map(&input);
|
||||
assert_eq!(ans, [4, 8, 12, 16, 20]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ fn main() {
|
||||
// `.into()` converts a type into an expected type.
|
||||
// If it is called where `String` is expected, it will convert `&str` to `String`.
|
||||
string("nice weather".into());
|
||||
// But if it is called where `&str` is expected, then `&str` is kept `&str` since no conversion is needed.
|
||||
// But if it is called where `&str` is expected, then `&str` is kept as `&str` since no conversion is needed.
|
||||
// If you remove the `#[allow(…)]` line, then Clippy will tell you to remove `.into()` below since it is a useless conversion.
|
||||
#[allow(clippy::useless_conversion)]
|
||||
string_slice("nice weather".into());
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// A basket of fruits in the form of a hash map needs to be defined. The key
|
||||
// represents the name of the fruit and the value represents how many of that
|
||||
// particular fruit is in the basket. You have to put at least 3 different
|
||||
// types of fruits (e.g apple, banana, mango) in the basket and the total count
|
||||
// types of fruits (e.g. apple, banana, mango) in the basket and the total count
|
||||
// of all the fruits should be at least 5.
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// This function returns how much icecream there is left in the fridge.
|
||||
// This function returns how much ice cream there is left in the fridge.
|
||||
// If it's before 22:00 (24-hour system), then 5 scoops are left. At 22:00,
|
||||
// someone eats it all, so no icecream is left (value 0). Return `None` if
|
||||
// someone eats it all, so no ice cream is left (value 0). Return `None` if
|
||||
// `hour_of_day` is higher than 23.
|
||||
fn maybe_icecream(hour_of_day: u16) -> Option<u16> {
|
||||
fn maybe_ice_cream(hour_of_day: u16) -> Option<u16> {
|
||||
match hour_of_day {
|
||||
0..=21 => Some(5),
|
||||
22..=23 => Some(0),
|
||||
@@ -21,19 +21,19 @@ mod tests {
|
||||
#[test]
|
||||
fn raw_value() {
|
||||
// Using `unwrap` is fine in a test.
|
||||
let icecreams = maybe_icecream(12).unwrap();
|
||||
let ice_creams = maybe_ice_cream(12).unwrap();
|
||||
|
||||
assert_eq!(icecreams, 5);
|
||||
assert_eq!(ice_creams, 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_icecream() {
|
||||
assert_eq!(maybe_icecream(0), Some(5));
|
||||
assert_eq!(maybe_icecream(9), Some(5));
|
||||
assert_eq!(maybe_icecream(18), Some(5));
|
||||
assert_eq!(maybe_icecream(22), Some(0));
|
||||
assert_eq!(maybe_icecream(23), Some(0));
|
||||
assert_eq!(maybe_icecream(24), None);
|
||||
assert_eq!(maybe_icecream(25), None);
|
||||
fn check_ice_cream() {
|
||||
assert_eq!(maybe_ice_cream(0), Some(5));
|
||||
assert_eq!(maybe_ice_cream(9), Some(5));
|
||||
assert_eq!(maybe_ice_cream(18), Some(5));
|
||||
assert_eq!(maybe_ice_cream(22), Some(0));
|
||||
assert_eq!(maybe_ice_cream(23), Some(0));
|
||||
assert_eq!(maybe_ice_cream(24), None);
|
||||
assert_eq!(maybe_ice_cream(25), None);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//
|
||||
// In short, this particular use case for boxes is for when you want to own a
|
||||
// value and you care only that it is a type which implements a particular
|
||||
// trait. To do so, The `Box` is declared as of type `Box<dyn Trait>` where
|
||||
// trait. To do so, the `Box` is declared as of type `Box<dyn Trait>` where
|
||||
// `Trait` is the trait the compiler looks for on any value used in that
|
||||
// context. For this exercise, that context is the potential errors which
|
||||
// can be returned in a `Result`.
|
||||
|
||||
@@ -4,7 +4,7 @@ fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
|
||||
|
||||
fn main() {
|
||||
let string1 = String::from("long string is long");
|
||||
// Solution1: You can move `strings2` out of the inner block so that it is
|
||||
// Solution 1: You can move `strings2` out of the inner block so that it is
|
||||
// not dropped before the print statement.
|
||||
let string2 = String::from("xyz");
|
||||
let result;
|
||||
@@ -21,7 +21,7 @@ fn main() {
|
||||
{
|
||||
let string2 = String::from("xyz");
|
||||
result = longest(&string1, &string2);
|
||||
// Solution2: You can move the print statement into the inner block so
|
||||
// Solution 2: You can move the print statement into the inner block so
|
||||
// that it is executed before `string2` is dropped.
|
||||
println!("The longest string is '{result}'");
|
||||
// `string2` dropped here (end of the inner scope).
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Added the attribute `macro_use` attribute.
|
||||
// Added the `macro_use` attribute.
|
||||
#[macro_use]
|
||||
mod macros {
|
||||
macro_rules! my_macro {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use std::mem;
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[allow(unused_variables, unused_assignments)]
|
||||
fn main() {
|
||||
let my_option: Option<&str> = None;
|
||||
@@ -11,17 +10,18 @@ fn main() {
|
||||
}
|
||||
|
||||
// A comma was missing.
|
||||
#[rustfmt::skip]
|
||||
let my_arr = &[
|
||||
-1, -2, -3,
|
||||
-4, -5, -6,
|
||||
];
|
||||
println!("My array! Here it is: {my_arr:?}");
|
||||
|
||||
let mut my_empty_vec = vec![1, 2, 3, 4, 5];
|
||||
let mut my_vec = vec![1, 2, 3, 4, 5];
|
||||
// `resize` mutates a vector instead of returning a new one.
|
||||
// `resize(0, …)` clears a vector, so it is better to use `clear`.
|
||||
my_empty_vec.clear();
|
||||
println!("This Vec is empty, see? {my_empty_vec:?}");
|
||||
my_vec.clear();
|
||||
println!("This Vec is empty, see? {my_vec:?}");
|
||||
|
||||
let mut value_a = 45;
|
||||
let mut value_b = 66;
|
||||
|
||||
@@ -74,7 +74,7 @@ pub fn init() -> Result<()> {
|
||||
|
||||
let workspace_manifest_content = fs::read_to_string(&workspace_manifest)
|
||||
.with_context(|| format!("Failed to read the file {}", workspace_manifest.display()))?;
|
||||
if !workspace_manifest_content.contains("[workspace]\n")
|
||||
if !workspace_manifest_content.contains("[workspace]")
|
||||
&& !workspace_manifest_content.contains("workspace.")
|
||||
{
|
||||
bail!(
|
||||
|
||||
Reference in New Issue
Block a user