From 1c27aeead908a7179b48f2bd70e43acfc730ffea Mon Sep 17 00:00:00 2001 From: Enrico Date: Wed, 1 Nov 2023 22:36:58 +0100 Subject: [PATCH] feat: add functions6.rs and move_semantics6.rs exercises about closures --- exercises/02_functions/README.md | 3 +- exercises/02_functions/functions6.rs | 20 +++++++++++++ .../06_move_semantics/move_semantics6.rs | 27 +++++++++++++++++ exercises/README.md | 2 +- rustlings-macros/info.toml | 29 +++++++++++++++++++ 5 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 exercises/02_functions/functions6.rs create mode 100644 exercises/06_move_semantics/move_semantics6.rs diff --git a/exercises/02_functions/README.md b/exercises/02_functions/README.md index 6662d0da..63ea0e82 100644 --- a/exercises/02_functions/README.md +++ b/exercises/02_functions/README.md @@ -1,8 +1,9 @@ # Functions Here, you'll learn how to write functions and how the Rust compiler can help you debug errors even -in more complex code. +in more complex code. You will also learn what is the difference with closures. ## Further information - [How Functions Work](https://doc.rust-lang.org/book/ch03-03-how-functions-work.html) +- [Closures](https://doc.rust-lang.org/book/ch13-01-closures.html) diff --git a/exercises/02_functions/functions6.rs b/exercises/02_functions/functions6.rs new file mode 100644 index 00000000..4a418785 --- /dev/null +++ b/exercises/02_functions/functions6.rs @@ -0,0 +1,20 @@ +// functions6.rs +// +// Here you can practice special functions called `closures`, that can capture +// variables of their parent context. +// Fix the code below to make it compile, without changing the two closure +// definitions. +// +// Execute `rustlings hint functions6` or use the `hint` watch subcommand for +// some hints. + +// I AM NOT DONE + +fn main() { + let closure_1 = |input_var: u32| -> u32 {input_var + outer_var}; + println!("Closure#1 returns {}", closure_1(5)); + + let closure_2 = |input_var| println!("Closure#2 (input_var {})", input_var); + closure_2(2); + closure_2("5"); +} diff --git a/exercises/06_move_semantics/move_semantics6.rs b/exercises/06_move_semantics/move_semantics6.rs new file mode 100644 index 00000000..ec17358f --- /dev/null +++ b/exercises/06_move_semantics/move_semantics6.rs @@ -0,0 +1,27 @@ +// move_semantics6.rs +// +// Here you will practice how mutable/immutable borrowing works in the context +// of a closure. +// +// Try to fix this code to make it compile and not panic. +// You can't change anything except removing 1 line. +// +// Execute `rustlings hint move_semantics7` or use the `hint` watch subcommand +// for a hint. + +// I AM NOT DONE + +fn main() { + let mut counter = 0; + + let mut increment = || { + counter += 1; + println!("counter: {}", counter); + }; + + increment(); + let _reborrowed_counter = &counter; + increment(); + + assert_eq!(counter, 2); +} diff --git a/exercises/README.md b/exercises/README.md index 237f2f1e..66003eff 100644 --- a/exercises/README.md +++ b/exercises/README.md @@ -3,7 +3,7 @@ | Exercise | Book Chapter | | ---------------------- | ------------------- | | variables | §3.1 | -| functions | §3.3 | +| functions | §3.3, §13.1 | | if | §3.5 | | primitive_types | §3.2, §4.3 | | vecs | §8.1 | diff --git a/rustlings-macros/info.toml b/rustlings-macros/info.toml index c1342d68..72a3162b 100644 --- a/rustlings-macros/info.toml +++ b/rustlings-macros/info.toml @@ -187,6 +187,21 @@ There are two solutions: 1. Add the `return` keyword before `num * num;` 2. Remove the semicolon `;` after `num * num`""" +[[exercises]] +name = "functions6" +path = "exercises/02_functions/functions6.rs" +mode = "compile" +hint = """ +Hint FIX #1: Closures can capture variables defined in the outer context. + +Hint FIX #2: Closures can infer both input and returned types, when they are not +specified in the signature. But the closure cannot be reused with different +input types. + +Read more about closures in the rust book dedicated section: +https://doc.rust-lang.org/book/ch13-01-closures.html +""" + # IF [[exercises]] @@ -391,6 +406,20 @@ The first problem is that `get_char` is taking ownership of the string. So Once you've fixed that, `string_uppercase`'s function signature will also need to be adjusted.""" +[[exercises]] +name = "move_semantics6" +path = "exercises/06_move_semantics/move_semantics6.rs" +mode = "compile" +hint = """ +When a closure capture a variable to modify it, it borrows that variable as a +mutable reference. In this exercise, as the closure mutably borrows `counter` +and is called later, any attempt to reborrow `counter` in between will lead to +an error. + +You cannot immutably borrow a variable if a mutable closure is +called later in the scope. +""" + # STRUCTS [[exercises]]