diff --git a/README.md b/README.md index 1758f639..d303083a 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,18 @@ -## 第一期 Rust 入门训练营-基础阶段 +## 2025年春季第一期 Rust 入门训练营-导学阶段基础测试 +**请在完成本实验后凭借排行榜分数截图练习班主任加入学习交流群** - -基础阶段实验同样将通过Rustlings进行测试,请按照以下步骤进行练习: +导学阶段将通过 Rustlings 进行测试,我们选取了 Rustlings 练习的前16道基础题目进行测试,确保您具备基本的编程能力,请按照以下步骤进行练习: 1. 在网络浏览器中用自己的 github id 登录 github.com。 -2. **fork 本仓库**,并按照下述引导进行答题,**在完成全部题目后请凭借排行榜成绩截图联系班主任进入专业阶段学习群**: +2. 请将本仓库 fork 到您的 github 账号下,然后参照以下步骤完成环境配置和实验提交: * 本地环境: 1. **安装Linux的环境**。对于windows的用户,推荐使用wsl2安装Ubuntu 22.04,也可以使用vmware等虚拟机进行安装。如果在这一步存在问题,请联系助教。 2. **创建ssh key,用于ssh方式克隆github代码**。在linux环境下,使用`ssh-keygen -t rsa -b 4096 -C "你的邮箱"`命令,创建ssh key,下面的选项全部直接敲回车即可。 随后使用` cat ~/.ssh/id_rsa.pub` 命令查看生成的公钥,并完整的复制下来。 在github仓库界面点击自己的头像,选择`settings`。进入到设置页面后,点击左侧的`SSH and GPG keys`选项。点击`New SSH key`选项,并将复制下来的内容粘贴上去,添加该ssh key的描述。随后点击`Add SSH key`,并一路点击确认即可。 3. **本地安装rust**。进入linux环境下,参考Arceos 教程 [Rust 开发环境配置 - ArceOS Tutorial Book (rcore-os.cn)](https://rcore-os.cn/arceos-tutorial-book/ch01-02.html) 中,找到Rust 开发环境配置的章节,相应配置即可,你可以同时将后续需要的环境也配置好. 4. **clone实验仓库到本地。**在前面点击链接生成的仓库中,同样点击醒目的 `code` 绿色按钮,选择`local`下的`ssh`选项,复制下面的链接。随后回到本地linux环境下,使用`git clone 复制的链接`的方式,将目标仓库clone到本地。随后,使用`ls`命令查看自己clone下来的文件夹,再使用`cd`命令进入到该文件夹下,使用 `cargo install --force --path .` 安装rustlings。 5. **练习rustlings**。使用vscode等编辑器,进入clone下来的目录下的`exercises`文件夹,执行`rustlings watch`依次查看完成情况,并依次完成对应的练习。 执行`rustlings run 练习名称`去运行对应练习,也可以使用`rustlings hint 练习名称`查看题解。 - 6. **提交完成情况**。当做完部分或所有练习之后,在rustlings目录下执行 `git add .; git commit -m "update"; git push` 命令,把更新提交到GithubClassroom的CI进行自动评测。你可以在github仓库页面的actions页面,看到你的CI提交结果,或者 https://opencamp.ai/Rust/camp/S01/stage/1?tab=rank上面查看自己的评分。 + 6. **提交完成情况**。当做完部分或所有练习之后,在rustlings目录下执行 `git add .; git commit -m "update"; git push` 命令,把更新提交到GithubClassroom的CI进行自动评测。你可以在github仓库页面的actions页面,看到你的CI提交结果,或者 https://opencamp.ai/Rust/camp/S01/stage/0?tab=rank 上面查看自己的评分。 * 在线环境: 1. 如果使用在线环境,在本网页的中上部可以看到一个醒目的 `code` 绿色按钮,点击后,可以进一步看到 `codespace` 标签和醒目的 `create codesapce on main` 绿色按钮。请点击这个绿色按钮,就可以进入到在线的ubuntu +vscode环境中 diff --git a/exercises/README.md b/exercises/README.md index c7effa95..40740ae2 100644 --- a/exercises/README.md +++ b/exercises/README.md @@ -1,4 +1,4 @@ -# Exercise to Book Chapter mapping +# Exercise to Book Chapter mappingd | Exercise | Book Chapter | | ---------------------- | ------------------- | diff --git a/exercises/functions/README.md b/exercises/functions/README.md new file mode 100644 index 00000000..6662d0da --- /dev/null +++ b/exercises/functions/README.md @@ -0,0 +1,8 @@ +# Functions + +Here, you'll learn how to write functions and how the Rust compiler can help you debug errors even +in more complex code. + +## Further information + +- [How Functions Work](https://doc.rust-lang.org/book/ch03-03-how-functions-work.html) diff --git a/exercises/functions/functions1.rs b/exercises/functions/functions1.rs new file mode 100644 index 00000000..d01d710e --- /dev/null +++ b/exercises/functions/functions1.rs @@ -0,0 +1,11 @@ +// functions1.rs +// Execute `rustlings hint functions1` or use the `hint` watch subcommand for a hint. + + + +fn call_me(){ + println!("Func1:hello world") +} +fn main() { + call_me(); +} diff --git a/exercises/functions/functions2.rs b/exercises/functions/functions2.rs new file mode 100644 index 00000000..a40777f1 --- /dev/null +++ b/exercises/functions/functions2.rs @@ -0,0 +1,14 @@ +// functions2.rs +// Execute `rustlings hint functions2` or use the `hint` watch subcommand for a hint. + + + +fn main() { + call_me(3); +} + +fn call_me(num:i32) { + for i in 0..num { + println!("Ring! Call number {}", i + 1); + } +} diff --git a/exercises/functions/functions3.rs b/exercises/functions/functions3.rs new file mode 100644 index 00000000..dd6931b2 --- /dev/null +++ b/exercises/functions/functions3.rs @@ -0,0 +1,14 @@ +// functions3.rs +// Execute `rustlings hint functions3` or use the `hint` watch subcommand for a hint. + + + +fn main() { + call_me(1); +} + +fn call_me(num: u32) { + for i in 0..num { + println!("Ring! Call number {}", i + 1); + } +} diff --git a/exercises/functions/functions4.rs b/exercises/functions/functions4.rs new file mode 100644 index 00000000..9e46c48e --- /dev/null +++ b/exercises/functions/functions4.rs @@ -0,0 +1,27 @@ +// functions4.rs +// Execute `rustlings hint functions4` or use the `hint` watch subcommand for a hint. + +// This store is having a sale where if the price is an even number, you get +// 10 Rustbucks off, but if it's an odd number, it's 3 Rustbucks off. +// (Don't worry about the function bodies themselves, we're only interested +// in the signatures for now. If anything, this is a good way to peek ahead +// to future exercises!) + + + +fn main() { + let original_price = 51; + println!("Your sale price is {}", sale_price(original_price)); +} + +fn sale_price(price: i32) -> i32 { + if is_even(price) { + price - 10 + } else { + price - 3 + } +} + +fn is_even(num: i32) -> bool { + num % 2 == 0 +} diff --git a/exercises/functions/functions5.rs b/exercises/functions/functions5.rs new file mode 100644 index 00000000..3da51720 --- /dev/null +++ b/exercises/functions/functions5.rs @@ -0,0 +1,13 @@ +// functions5.rs +// Execute `rustlings hint functions5` or use the `hint` watch subcommand for a hint. + + + +fn main() { + let answer = square(3); + println!("The square of 3 is {}", answer); +} + +fn square(num: i32) -> i32 { + num * num +} diff --git a/exercises/if/README.md b/exercises/if/README.md new file mode 100644 index 00000000..b52c3922 --- /dev/null +++ b/exercises/if/README.md @@ -0,0 +1,7 @@ +# If + +`if`, the most basic (but still surprisingly versatile!) type of control flow, is what you'll learn here. + +## Further information + +- [Control Flow - if expressions](https://doc.rust-lang.org/book/ch03-05-control-flow.html#if-expressions) diff --git a/exercises/if/if1.rs b/exercises/if/if1.rs new file mode 100644 index 00000000..69a89b8b --- /dev/null +++ b/exercises/if/if1.rs @@ -0,0 +1,31 @@ +// if1.rs +// Execute `rustlings hint if1` or use the `hint` watch subcommand for a hint. + + +pub fn bigger(a: i32, b: i32) -> i32 { + // Complete this function to return the bigger number! + // Do not use: + // - another function call + // - additional variables + if a>b{ + a + }else{ + b + } +} + +// Don't mind this for now :) +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn ten_is_bigger_than_eight() { + assert_eq!(10, bigger(10, 8)); + } + + #[test] + fn fortytwo_is_bigger_than_thirtytwo() { + assert_eq!(42, bigger(32, 42)); + } +} diff --git a/exercises/if/if2.rs b/exercises/if/if2.rs new file mode 100644 index 00000000..70ac1fdb --- /dev/null +++ b/exercises/if/if2.rs @@ -0,0 +1,38 @@ +// if2.rs + +// Step 1: Make me compile! +// Step 2: Get the bar_for_fuzz and default_to_baz tests passing! +// Execute `rustlings hint if2` or use the `hint` watch subcommand for a hint. + + + +pub fn foo_if_fizz(fizzish: &str) -> &str { + if fizzish == "fizz" { + "foo" + } else if fizzish == "fuzz" { + "bar" + }else{ + "baz" + } +} + +// No test changes needed! +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn foo_for_fizz() { + assert_eq!(foo_if_fizz("fizz"), "foo") + } + + #[test] + fn bar_for_fuzz() { + assert_eq!(foo_if_fizz("fuzz"), "bar") + } + + #[test] + fn default_to_baz() { + assert_eq!(foo_if_fizz("literally anything"), "baz") + } +} diff --git a/exercises/if/if3.rs b/exercises/if/if3.rs new file mode 100644 index 00000000..de252677 --- /dev/null +++ b/exercises/if/if3.rs @@ -0,0 +1,55 @@ +// if3.rs +// +// Execute `rustlings hint if3` or use the `hint` watch subcommand for a hint. + + + +pub fn animal_habitat(animal: &str) -> &'static str { + let identifier = if animal == "crab" { + 1 + } else if animal == "gopher" { + 2 + } else if animal == "snake" { + 3 + } else { + 4 + }; + + // DO NOT CHANGE THIS STATEMENT BELOW + let habitat = if identifier == 1 { + "Beach" + } else if identifier == 2 { + "Burrow" + } else if identifier == 3 { + "Desert" + } else { + "Unknown" + }; + + habitat +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn gopher_lives_in_burrow() { + assert_eq!(animal_habitat("gopher"), "Burrow") + } + + #[test] + fn snake_lives_in_desert() { + assert_eq!(animal_habitat("snake"), "Desert") + } + + #[test] + fn crab_lives_on_beach() { + assert_eq!(animal_habitat("crab"), "Beach") + } + + #[test] + fn unknown_animal() { + assert_eq!(animal_habitat("dinosaur"), "Unknown") + } +} diff --git a/exercises/intro/README.md b/exercises/intro/README.md new file mode 100644 index 00000000..d32e4a8b --- /dev/null +++ b/exercises/intro/README.md @@ -0,0 +1,8 @@ +# Intro + +Rust uses the `print!` and `println!` macros to print text to the console. + +## Further information + +- [Hello World](https://doc.rust-lang.org/rust-by-example/hello.html) +- [Formatted print](https://doc.rust-lang.org/rust-by-example/hello/print.html) diff --git a/exercises/intro/intro1.rs b/exercises/intro/intro1.rs new file mode 100644 index 00000000..1901f946 --- /dev/null +++ b/exercises/intro/intro1.rs @@ -0,0 +1,30 @@ +// intro1.rs +// About this `I AM NOT DONE` thing: +// We sometimes encourage you to keep trying things on a given exercise, even +// after you already figured it out. If you got everything working and feel +// ready for the next exercise, remove the `I AM NOT DONE` comment below. +// Execute `rustlings hint intro1` or use the `hint` watch subcommand for a hint. +// +// If you're running this using `rustlings watch`: The exercise file will be reloaded +// when you change one of the lines below! Try adding a `println!` line, or try changing +// what it outputs in your terminal. Try removing a semicolon and see what happens! + + + +fn main() { + println!("Hello adajo!"); + println!(r#" welcome to... "#); + println!(r#" _ _ _ "#); + println!(r#" _ __ _ _ ___| |_| (_)_ __ __ _ ___ "#); + println!(r#" | '__| | | / __| __| | | '_ \ / _` / __| "#); + println!(r#" | | | |_| \__ \ |_| | | | | | (_| \__ \ "#); + println!(r#" |_| \__,_|___/\__|_|_|_| |_|\__, |___/ "#); + println!(r#" |___/ "#); + println!(); + println!("This exercise compiles successfully. The remaining exercises contain a compiler"); + println!("or logic error. The central concept behind Rustlings is to fix these errors and"); + println!("solve the exercises. Good luck!"); + println!(); + println!("The source for this exercise is in `exercises/intro/intro1.rs`. Have a look!"); + println!("Going forward, the source of the exercises will always be in the success/failure output."); +} diff --git a/exercises/intro/intro2.rs b/exercises/intro/intro2.rs new file mode 100644 index 00000000..d8ec0030 --- /dev/null +++ b/exercises/intro/intro2.rs @@ -0,0 +1,9 @@ +// intro2.rs +// Make the code print a greeting to the world. +// Execute `rustlings hint intro2` or use the `hint` watch subcommand for a hint. + + + +fn main() { + println!("Hello {}!","dahsdioahsdoafb"); +} diff --git a/exercises/quiz1.rs b/exercises/quiz1.rs new file mode 100644 index 00000000..ba35706e --- /dev/null +++ b/exercises/quiz1.rs @@ -0,0 +1,32 @@ +// quiz1.rs +// This is a quiz for the following sections: +// - Variables +// - Functions +// - If + +// Mary is buying apples. The price of an apple is calculated as follows: +// - An apple costs 2 rustbucks. +// - If Mary buys more than 40 apples, each apple only costs 1 rustbuck! +// Write a function that calculates the price of an order of apples given +// the quantity bought. No hints this time! + + + +// Put your function here! +fn calculate_price_of_apples(num:u32)->u32 { + if num<=40 { num*2 } else { num } +} + +// Don't modify this function! +#[test] +fn verify_test() { + let price1 = calculate_price_of_apples(35); + let price2 = calculate_price_of_apples(40); + let price3 = calculate_price_of_apples(41); + let price4 = calculate_price_of_apples(65); + + assert_eq!(70, price1); + assert_eq!(80, price2); + assert_eq!(41, price3); + assert_eq!(65, price4); +} diff --git a/exercises/variables/README.md b/exercises/variables/README.md new file mode 100644 index 00000000..11a7a78a --- /dev/null +++ b/exercises/variables/README.md @@ -0,0 +1,9 @@ +# Variables + +In Rust, variables are immutable by default. +When a variable is immutable, once a value is bound to a name, you can’t change that value. +You can make them mutable by adding mut in front of the variable name. + +## Further information + +- [Variables and Mutability](https://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html) diff --git a/exercises/variables/variables1.rs b/exercises/variables/variables1.rs new file mode 100644 index 00000000..b0ad72da --- /dev/null +++ b/exercises/variables/variables1.rs @@ -0,0 +1,9 @@ +// variables1.rs +// Make me compile! +// Execute `rustlings hint variables1` or use the `hint` watch subcommand for a hint. + + +fn main() { + let x = 5; + println!("x has the value {}", x); +} diff --git a/exercises/variables/variables2.rs b/exercises/variables/variables2.rs new file mode 100644 index 00000000..1e381303 --- /dev/null +++ b/exercises/variables/variables2.rs @@ -0,0 +1,13 @@ +// variables2.rs +// Execute `rustlings hint variables2` or use the `hint` watch subcommand for a hint. + + + +fn main() { + let x:i32=42; + if x == 10 { + println!("x is ten!"); + } else { + println!("x is not ten!"); + } +} diff --git a/exercises/variables/variables3.rs b/exercises/variables/variables3.rs new file mode 100644 index 00000000..b64d8fd8 --- /dev/null +++ b/exercises/variables/variables3.rs @@ -0,0 +1,9 @@ +// variables3.rs +// Execute `rustlings hint variables3` or use the `hint` watch subcommand for a hint. + + + +fn main() { + let x: i32=10; + println!("Number {}", x); +} diff --git a/exercises/variables/variables4.rs b/exercises/variables/variables4.rs new file mode 100644 index 00000000..a6e54571 --- /dev/null +++ b/exercises/variables/variables4.rs @@ -0,0 +1,11 @@ +// variables4.rs +// Execute `rustlings hint variables4` or use the `hint` watch subcommand for a hint. + + + +fn main() { + let mut x = 3; + println!("Number {}", x); + x = 5; // don't change this line + println!("Number {}", x); +} diff --git a/exercises/variables/variables5.rs b/exercises/variables/variables5.rs new file mode 100644 index 00000000..14aec8c0 --- /dev/null +++ b/exercises/variables/variables5.rs @@ -0,0 +1,11 @@ +// variables5.rs +// Execute `rustlings hint variables5` or use the `hint` watch subcommand for a hint. + + + +fn main() { + let number = "T-H-R-E-E"; // don't change this line + println!("Spell a Number : {}", number); + let number = 3; // don't rename this variable + println!("Number plus two is : {}", number + 2); +} diff --git a/exercises/variables/variables6.rs b/exercises/variables/variables6.rs new file mode 100644 index 00000000..b11c799b --- /dev/null +++ b/exercises/variables/variables6.rs @@ -0,0 +1,9 @@ +// variables6.rs +// Execute `rustlings hint variables6` or use the `hint` watch subcommand for a hint. + + + +const NUMBER:i32 = 3; +fn main() { + println!("Number {}", NUMBER); +} diff --git a/info.toml b/info.toml index 09f5fa99..19ae5ebf 100644 --- a/info.toml +++ b/info.toml @@ -8,396 +8,260 @@ # Remove the I AM NOT DONE comment in the exercises/intro/intro1.rs file # to move on to the next exercise.""" - -# VECS - [[exercises]] -name = "vecs1" -path = "exercises/vecs/vecs1.rs" -mode = "test" +name = "intro2" +path = "exercises/intro/intro2.rs" +mode = "compile" hint = """ -In Rust, there are two ways to define a Vector. -1. One way is to use the `Vec::new()` function to create a new vector - and fill it with the `push()` method. -2. The second way, which is simpler is to use the `vec![]` macro and - define your elements inside the square brackets. -Check this chapter: https://doc.rust-lang.org/stable/book/ch08-01-vectors.html -of the Rust book to learn more. -""" - +Add an argument after the format string.""" [[exercises]] -name = "vecs2" -path = "exercises/vecs/vecs2.rs" -mode = "test" +name = "intro3" +path = "exercises/intro/intro2.rs" +mode = "compile" hint = """ -Hint 1: In the code, the variable `element` represents an item from the Vec as it is being iterated. -Can you try multiplying this? - -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 -number that way. - -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? -""" - -# MOVE SEMANTICS - - +Add an argument after the format string.""" [[exercises]] -name = "move_semantics4" -path = "exercises/move_semantics/move_semantics4.rs" +name = "intro4" +path = "exercises/intro/intro2.rs" mode = "compile" hint = """ -Stop reading whenever you feel like you have enough direction :) Or try -doing one step and then fixing the compiler errors that result! -So the end goal is to: - - get rid of the first line in main that creates the new vector - - so then `vec0` doesn't exist, so we can't pass it to `fill_vec` - - `fill_vec` has had its signature changed, which our call should reflect - - since we're not creating a new vec in `main` anymore, we need to create - a new vec in `fill_vec`, similarly to the way we did in `main`""" - +Add an argument after the format string.""" [[exercises]] -name = "move_semantics5" -path = "exercises/move_semantics/move_semantics5.rs" +name = "intro5" +path = "exercises/intro/intro2.rs" mode = "compile" hint = """ -Carefully reason about the range in which each mutable reference is in -scope. Does it help to update the value of referent (x) immediately after -the mutable reference is taken? Read more about 'Mutable References' -in the book's section References and Borrowing': -https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html#mutable-references. -""" - +Add an argument after the format string.""" [[exercises]] -name = "move_semantics6" -path = "exercises/move_semantics/move_semantics6.rs" +name = "intro6" +path = "exercises/intro/intro2.rs" mode = "compile" hint = """ -To find the answer, you can consult the book section "References and Borrowing": -https://doc.rust-lang.org/stable/book/ch04-02-references-and-borrowing.html -The first problem is that `get_char` is taking ownership of the string. -So `data` is moved and can't be used for `string_uppercase` -`data` is moved to `get_char` first, meaning that `string_uppercase` cannot manipulate the data. -Once you've fixed that, `string_uppercase`'s function signature will also need to be adjusted. -Can you figure out how? - -Another hint: it has to do with the `&` character.""" - -# STRUCTS - +Add an argument after the format string.""" [[exercises]] -name = "structs1" -path = "exercises/structs/structs1.rs" -mode = "test" +name = "intro7" +path = "exercises/intro/intro2.rs" +mode = "compile" hint = """ -Rust has more than one type of struct. Three actually, all variants are used to package related data together. -There are normal (or classic) structs. These are named collections of related data stored in fields. -Tuple structs are basically just named tuples. -Finally, Unit-like structs. These don't have any fields and are useful for generics. - -In this exercise you need to complete and implement one of each kind. -Read more about structs in The Book: https://doc.rust-lang.org/book/ch05-01-defining-structs.html""" - - -# STRINGS - - +Add an argument after the format string.""" [[exercises]] -name = "strings3" -path = "exercises/strings/strings3.rs" -mode = "test" +name = "intro8" +path = "exercises/intro/intro2.rs" +mode = "compile" hint = """ -There's tons of useful standard library functions for strings. Let's try and use some of -them: ! - -For the compose_me method: You can either use the `format!` macro, or convert the string -slice into an owned string, which you can then freely extend.""" - +Add an argument after the format string.""" [[exercises]] -name = "strings4" -path = "exercises/strings/strings4.rs" +name = "intro9" +path = "exercises/intro/intro2.rs" mode = "compile" -hint = "No hints this time ;)" - -# MODULES - - +hint = """ +Add an argument after the format string.""" [[exercises]] -name = "modules2" -path = "exercises/modules/modules2.rs" +name = "intro10" +path = "exercises/intro/intro2.rs" mode = "compile" hint = """ -The delicious_snacks module is trying to present an external interface that is -different than its internal structure (the `fruits` and `veggies` modules and -associated constants). Complete the `use` statements to fit the uses in main and -find the one keyword missing for both constants. -Learn more at https://doc.rust-lang.org/book/ch07-04-bringing-paths-into-scope-with-the-use-keyword.html#re-exporting-names-with-pub-use""" - -# HASHMAPS - +Add an argument after the format string.""" [[exercises]] -name = "hashmaps1" -path = "exercises/hashmaps/hashmaps1.rs" -mode = "test" +name = "intro11" +path = "exercises/intro/intro2.rs" +mode = "compile" hint = """ -Hint 1: Take a look at the return type of the function to figure out - the type for the `basket`. -Hint 2: Number of fruits should be at least 5. And you have to put - at least three different types of fruits. -""" - +Add an argument after the format string.""" [[exercises]] -name = "hashmaps2" -path = "exercises/hashmaps/hashmaps2.rs" -mode = "test" +name = "intro12" +path = "exercises/intro/intro2.rs" +mode = "compile" hint = """ -Use the `entry()` and `or_insert()` methods of `HashMap` to achieve this. -Learn more at https://doc.rust-lang.org/stable/book/ch08-03-hash-maps.html#only-inserting-a-value-if-the-key-has-no-value -""" - +Add an argument after the format string.""" [[exercises]] -name = "hashmaps3" -path = "exercises/hashmaps/hashmaps3.rs" -mode = "test" +name = "intro13" +path = "exercises/intro/intro2.rs" +mode = "compile" hint = """ -Hint 1: Use the `entry()` and `or_insert()` methods of `HashMap` to insert entries corresponding to each team in the scores table. -Learn more at https://doc.rust-lang.org/stable/book/ch08-03-hash-maps.html#only-inserting-a-value-if-the-key-has-no-value -Hint 2: If there is already an entry for a given key, the value returned by `entry()` can be updated based on the existing value. -Learn more at https://doc.rust-lang.org/book/ch08-03-hash-maps.html#updating-a-value-based-on-the-old-value -""" - -# QUIZ 2 - +Add an argument after the format string.""" [[exercises]] -name = "quiz2" -path = "exercises/quiz2.rs" -mode = "test" -hint = "No hints this time ;)" - -# OPTIONS - -[[exercises]] -name = "options1" -path = "exercises/options/options1.rs" -mode = "test" +name = "intro14" +path = "exercises/intro/intro2.rs" +mode = "compile" hint = """ -Options can have a Some value, with an inner value, or a None value, without an inner value. -There's multiple ways to get at the inner value, you can use unwrap, or pattern match. Unwrapping -is the easiest, but how do you do it safely so that it doesn't panic in your face later?""" - - -# Generics - +Add an argument after the format string.""" [[exercises]] -name = "generics1" -path = "exercises/generics/generics1.rs" +name = "intro15" +path = "exercises/intro/intro2.rs" mode = "compile" hint = """ -Vectors in Rust make use of generics to create dynamically sized arrays of any type. -You need to tell the compiler what type we are pushing onto this vector.""" - +Add an argument after the format string.""" [[exercises]] -name = "generics2" -path = "exercises/generics/generics2.rs" -mode = "test" +name = "intro16" +path = "exercises/intro/intro2.rs" +mode = "compile" hint = """ -Currently we are wrapping only values of type 'u32'. -Maybe we could update the explicit references to this data type somehow? - -If you are still stuck https://doc.rust-lang.org/stable/book/ch10-01-syntax.html#in-method-definitions -""" - -# TRAITS +Add an argument after the format string.""" +# VARIABLES [[exercises]] -name = "traits3" -path = "exercises/traits/traits3.rs" -mode = "test" +name = "variables1" +path = "exercises/variables/variables1.rs" +mode = "compile" hint = """ -Traits can have a default implementation for functions. Structs that implement -the trait can then use the default version of these functions if they choose not -implement the function themselves. - -See the documentation at: https://doc.rust-lang.org/book/ch10-02-traits.html#default-implementations -""" +The declaration on line 8 is missing a keyword that is needed in Rust +to create a new variable binding.""" [[exercises]] -name = "traits4" -path = "exercises/traits/traits4.rs" -mode = "test" +name = "variables2" +path = "exercises/variables/variables2.rs" +mode = "compile" hint = """ -Instead of using concrete types as parameters you can use traits. Try replacing the -'??' with 'impl ' - -See the documentation at: https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters -""" - - -# QUIZ 3 +The compiler message is saying that Rust cannot infer the type that the +variable binding `x` has with what is given here. +What happens if you annotate line 7 with a type annotation? +What if you give x a value? +What if you do both? +What type should x be, anyway? +What if x is the same type as 10? What if it's a different type?""" [[exercises]] -name = "quiz3" -path = "exercises/quiz3.rs" -mode = "test" +name = "variables3" +path = "exercises/variables/variables3.rs" +mode = "compile" hint = """ -To find the best solution to this challenge you're going to need to think back to your -knowledge of traits, specifically Trait Bound Syntax - you may also need this: `use std::fmt::Display;`.""" - -# LIFETIMES +Oops! In this exercise, we have a variable binding that we've created on +line 7, and we're trying to use it on line 8, but we haven't given it a +value. We can't print out something that isn't there; try giving x a value! +This is an error that can cause bugs that's very easy to make in any +programming language -- thankfully the Rust compiler has caught this for us!""" [[exercises]] -name = "lifetimes1" -path = "exercises/lifetimes/lifetimes1.rs" +name = "variables4" +path = "exercises/variables/variables4.rs" mode = "compile" hint = """ -Let the compiler guide you. Also take a look at the book if you need help: -https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html""" +In Rust, variable bindings are immutable by default. But here we're trying +to reassign a different value to x! There's a keyword we can use to make +a variable binding mutable instead.""" [[exercises]] -name = "lifetimes2" -path = "exercises/lifetimes/lifetimes2.rs" +name = "variables5" +path = "exercises/variables/variables5.rs" mode = "compile" hint = """ -Remember that the generic lifetime 'a will get the concrete lifetime that is equal to the smaller of the lifetimes of x and y. -You can take at least two paths to achieve the desired result while keeping the inner block: -1. Move the string2 declaration to make it live as long as string1 (how is result declared?) -2. Move println! into the inner block""" +In variables4 we already learned how to make an immutable variable mutable +using a special keyword. Unfortunately this doesn't help us much in this exercise +because we want to assign a different typed value to an existing variable. Sometimes +you may also like to reuse existing variable names because you are just converting +values to different types like in this exercise. +Fortunately Rust has a powerful solution to this problem: 'Shadowing'! +You can read more about 'Shadowing' in the book's section 'Variables and Mutability': +https://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html#shadowing +Try to solve this exercise afterwards using this technique.""" [[exercises]] -name = "lifetimes3" -path = "exercises/lifetimes/lifetimes3.rs" +name = "variables6" +path = "exercises/variables/variables6.rs" mode = "compile" hint = """ -If you use a lifetime annotation in a struct's fields, where else does it need to be added?""" +We know about variables and mutability, but there is another important type of +variable available: constants. +Constants are always immutable and they are declared with keyword 'const' rather +than keyword 'let'. +Constants types must also always be annotated. + +Read more about constants and the differences between variables and constants under 'Constants' in the book's section 'Variables and Mutability': +https://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html#constants +""" -# STANDARD LIBRARY TYPES +# FUNCTIONS [[exercises]] -name = "iterators1" -path = "exercises/iterators/iterators1.rs" +name = "functions1" +path = "exercises/functions/functions1.rs" mode = "compile" hint = """ -Step 1: -We need to apply something to the collection `my_fav_fruits` before we start to go through -it. What could that be? Take a look at the struct definition for a vector for inspiration: -https://doc.rust-lang.org/std/vec/struct.Vec.html -Step 2 & step 3: -Very similar to the lines above and below. You've got this! -Step 4: -An iterator goes through all elements in a collection, but what if we've run out of -elements? What should we expect here? If you're stuck, take a look at -https://doc.rust-lang.org/std/iter/trait.Iterator.html for some ideas. -""" +This main function is calling a function that it expects to exist, but the +function doesn't exist. It expects this function to have the name `call_me`. +It expects this function to not take any arguments and not return a value. +Sounds a lot like `main`, doesn't it?""" [[exercises]] -name = "iterators2" -path = "exercises/iterators/iterators2.rs" -mode = "test" +name = "functions2" +path = "exercises/functions/functions2.rs" +mode = "compile" hint = """ -Step 1 -The variable `first` is a `char`. It needs to be capitalized and added to the -remaining characters in `c` in order to return the correct `String`. -The remaining characters in `c` can be viewed as a string slice using the -`as_str` method. -The documentation for `char` contains many useful methods. -https://doc.rust-lang.org/std/primitive.char.html - -Step 2 -Create an iterator from the slice. Transform the iterated values by applying -the `capitalize_first` function. Remember to collect the iterator. - -Step 3. -This is surprisingly similar to the previous solution. Collect is very powerful -and very general. Rust just needs to know the desired type.""" - -# SMART POINTERS +Rust requires that all parts of a function's signature have type annotations, +but `call_me` is missing the type annotation of `num`.""" [[exercises]] -name = "box1" -path = "exercises/smart_pointers/box1.rs" -mode = "test" +name = "functions3" +path = "exercises/functions/functions3.rs" +mode = "compile" hint = """ -Step 1 -The compiler's message should help: since we cannot store the value of the actual type -when working with recursive types, we need to store a reference (pointer) to its value. -We should, therefore, place our `List` inside a `Box`. More details in the book here: -https://doc.rust-lang.org/book/ch15-01-box.html#enabling-recursive-types-with-boxes - -Step 2 -Creating an empty list should be fairly straightforward (hint: peek at the assertions). -For a non-empty list keep in mind that we want to use our Cons "list builder". -Although the current list is one of integers (i32), feel free to change the definition -and try other types! -""" +This time, the function *declaration* is okay, but there's something wrong +with the place where we're calling the function. +As a reminder, you can freely play around with different solutions in Rustlings! +Watch mode will only jump to the next exercise if you remove the I AM NOT DONE comment.""" [[exercises]] -name = "rc1" -path = "exercises/smart_pointers/rc1.rs" +name = "functions4" +path = "exercises/functions/functions4.rs" mode = "compile" hint = """ -This is a straightforward exercise to use the Rc type. Each Planet has -ownership of the Sun, and uses Rc::clone() to increment the reference count of the Sun. -After using drop() to move the Planets out of scope individually, the reference count goes down. -In the end the sun only has one reference again, to itself. See more at: -https://doc.rust-lang.org/book/ch15-04-rc.html +The error message points to line 17 and says it expects a type after the +`->`. This is where the function's return type should be -- take a look at +the `is_even` function for an example! -* Unfortunately Pluto is no longer considered a planet :( -""" +Also: Did you figure out that, technically, u32 would be the more fitting type +for the prices here, since they can't be negative? If so, kudos!""" [[exercises]] -name = "arc1" -path = "exercises/smart_pointers/arc1.rs" +name = "functions5" +path = "exercises/functions/functions5.rs" mode = "compile" hint = """ -Make `shared_numbers` be an `Arc` from the numbers vector. Then, in order -to avoid creating a copy of `numbers`, you'll need to create `child_numbers` -inside the loop but still in the main thread. - -`child_numbers` should be a clone of the Arc of the numbers instead of a -thread-local copy of the numbers. +This is a really common error that can be fixed by removing one character. +It happens because Rust distinguishes between expressions and statements: expressions return a value based on their operand(s), and statements simply return a () type which behaves just like `void` in C/C++ language. +We want to return a value of `i32` type from the `square` function, but it is returning a `()` type... +They are not the same. There are two solutions: +1. Add a `return` ahead of `num * num;` +2. remove `;`, make it to be `num * num`""" -This is a simple exercise if you understand the underlying concepts, but if this -is too much of a struggle, consider reading through all of Chapter 16 in the book: -https://doc.rust-lang.org/stable/book/ch16-00-concurrency.html -""" +# IF [[exercises]] -name = "cow1" -path = "exercises/smart_pointers/cow1.rs" +name = "if1" +path = "exercises/if/if1.rs" mode = "test" hint = """ -If Cow already owns the data it doesn't need to clone it when to_mut() is called. - -Check out https://doc.rust-lang.org/std/borrow/enum.Cow.html for documentation -on the `Cow` type. -""" - -# MACROS +It's possible to do this in one line if you would like! +Some similar examples from other languages: +- In C(++) this would be: `a > b ? a : b` +- In Python this would be: `a if a > b else b` +Remember in Rust that: +- the `if` condition does not need to be surrounded by parentheses +- `if`/`else` conditionals are expressions +- Each condition is followed by a `{}` block.""" [[exercises]] -name = "macros1" -path = "exercises/macros/macros1.rs" -mode = "compile" +name = "if2" +path = "exercises/if/if2.rs" +mode = "test" hint = """ -When you call a macro, you need to add something special compared to a -regular function call. If you're stuck, take a look at what's inside -`my_macro`.""" +For that first compiler error, it's important in Rust that each conditional +block returns the same type! To get the tests passing, you will need a couple +conditions checking different input values.""" [[exercises]] -name = "macros2" -path = "exercises/macros/macros2.rs" -mode = "compile" +name = "if3" +path = "exercises/if/if3.rs" +mode = "test" hint = """ -Macros don't quite play by the same rules as the rest of Rust, in terms of -what's available where. - -Unlike other things in Rust, the order of "where you define a macro" versus -"where you use it" actually matters.""" - - - +In Rust, every arm of an `if` expression has to return the same type of value. Make sure the type is consistent across all arms.""" +# QUIZ 1 +[[exercises]] +name = "quiz1" +path = "exercises/quiz1.rs" +mode = "test" +hint = "No hints this time ;)" \ No newline at end of file diff --git a/temp_19928_ThreadId1.exe b/temp_19928_ThreadId1.exe new file mode 100644 index 00000000..f2029d7b Binary files /dev/null and b/temp_19928_ThreadId1.exe differ diff --git a/temp_22640_ThreadId1.exe b/temp_22640_ThreadId1.exe new file mode 100644 index 00000000..f6f9d216 Binary files /dev/null and b/temp_22640_ThreadId1.exe differ diff --git a/temp_24776_ThreadId1.exe b/temp_24776_ThreadId1.exe new file mode 100644 index 00000000..c6354b4e Binary files /dev/null and b/temp_24776_ThreadId1.exe differ diff --git a/temp_25924_ThreadId1.exe b/temp_25924_ThreadId1.exe new file mode 100644 index 00000000..d35d6cf2 Binary files /dev/null and b/temp_25924_ThreadId1.exe differ