Skip to content

Commit c26e739

Browse files
committed
Update closures
1 parent b85951e commit c26e739

3 files changed

Lines changed: 62 additions & 4 deletions

File tree

exercises/18_closures/closures1.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
//
1111
// Execute `rustlings hint closures1` or use the `hint` watch subcommand for a hint.
1212

13-
// I AM NOT DONE
14-
1513

1614
trait Doorman {
1715
fn greet_customer(&self, customer_name: &str);

rustlings-macros/info.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -877,8 +877,7 @@ https://doc.rust-lang.org/book/ch11-01-writing-tests.html#checking-for-panics-wi
877877

878878
[[exercises]]
879879
name = "closures1"
880-
path = "exercises/18_closures/closures1.rs"
881-
mode = "compile"
880+
dir = "18_closures"
882881
hint = """
883882
Self is a concept that is only used in struct/enum methods.
884883

solutions/18_closures/closures1.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// closures1.rs
2+
//
3+
// "Why do we even need closures?" is a question that gets asked from time to time.
4+
// While it's true that most things that closures can do can also be done with
5+
// regular old structs and enums, closures can make things a lot more clear with a lot
6+
// less clutter compared to structs.
7+
//
8+
// Below is a good example of how one could implement a capturing closure using structs,
9+
// and how closures simplifies this greatly.
10+
//
11+
// Execute `rustlings hint closures1` or use the `hint` watch subcommand for a hint.
12+
13+
trait Doorman {
14+
fn greet_customer(&self, customer_name: &str);
15+
}
16+
17+
struct GreeterWithState<'a> {
18+
greeting: &'a str,
19+
}
20+
21+
impl Doorman for GreeterWithState<'_> {
22+
fn greet_customer(&self, customer_name: &str) {
23+
println!("{}, {}?", self.greeting, customer_name);
24+
}
25+
}
26+
27+
fn greet_customers(doorman: impl Doorman) {
28+
doorman.greet_customer("Bill");
29+
doorman.greet_customer("Alex");
30+
doorman.greet_customer("John");
31+
doorman.greet_customer("Jessie");
32+
}
33+
34+
fn greet_customers_closure(doorman: impl Fn(&str)) {
35+
doorman("Bill");
36+
doorman("Alex");
37+
doorman("John");
38+
doorman("Jessie");
39+
}
40+
41+
fn main() {
42+
let greeting = String::from("Hello! How are you");
43+
44+
// Method 1 for passing in functions with state.
45+
// Just create a struct, store the state, and add a method.
46+
// If you need to be generic, it can be a trait method.
47+
let doorman = GreeterWithState {
48+
greeting: &greeting,
49+
};
50+
greet_customers(doorman);
51+
52+
// Method 2 for passing in functions with state.
53+
// Notice that the body of this closure is exactly the same
54+
// as GreeterWithState's Doorman implementation.
55+
//
56+
// This makes things much cleaner with less clutter, but
57+
// we are forgetting something very important.
58+
greet_customers_closure(|customer_name| {
59+
println!("{}, {}?", greeting, customer_name); // Capture greeting by reference
60+
})
61+
}

0 commit comments

Comments
 (0)