mirror of
https://github.com/rust-lang/rustlings.git
synced 2024-12-26 00:00:03 +03:00
Update closures
This commit is contained in:
parent
286e803d40
commit
d9cfdf7c65
|
@ -10,8 +10,6 @@
|
||||||
//
|
//
|
||||||
// Execute `rustlings hint closures1` or use the `hint` watch subcommand for a hint.
|
// Execute `rustlings hint closures1` or use the `hint` watch subcommand for a hint.
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
|
|
||||||
trait Doorman {
|
trait Doorman {
|
||||||
fn greet_customer(&self, customer_name: &str);
|
fn greet_customer(&self, customer_name: &str);
|
||||||
|
|
|
@ -881,8 +881,7 @@ https://doc.rust-lang.org/book/ch11-01-writing-tests.html#checking-for-panics-wi
|
||||||
|
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
name = "closures1"
|
name = "closures1"
|
||||||
path = "exercises/18_closures/closures1.rs"
|
dir = "18_closures"
|
||||||
mode = "compile"
|
|
||||||
hint = """
|
hint = """
|
||||||
Self is a concept that is only used in struct/enum methods.
|
Self is a concept that is only used in struct/enum methods.
|
||||||
|
|
||||||
|
|
61
solutions/18_closures/closures1.rs
Normal file
61
solutions/18_closures/closures1.rs
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
// closures1.rs
|
||||||
|
//
|
||||||
|
// "Why do we even need closures?" is a question that gets asked from time to time.
|
||||||
|
// While it's true that most things that closures can do can also be done with
|
||||||
|
// regular old structs and enums, closures can make things a lot more clear with a lot
|
||||||
|
// less clutter compared to structs.
|
||||||
|
//
|
||||||
|
// Below is a good example of how one could implement a capturing closure using structs,
|
||||||
|
// and how closures simplifies this greatly.
|
||||||
|
//
|
||||||
|
// Execute `rustlings hint closures1` or use the `hint` watch subcommand for a hint.
|
||||||
|
|
||||||
|
trait Doorman {
|
||||||
|
fn greet_customer(&self, customer_name: &str);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct GreeterWithState<'a> {
|
||||||
|
greeting: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Doorman for GreeterWithState<'_> {
|
||||||
|
fn greet_customer(&self, customer_name: &str) {
|
||||||
|
println!("{}, {}?", self.greeting, customer_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn greet_customers(doorman: impl Doorman) {
|
||||||
|
doorman.greet_customer("Bill");
|
||||||
|
doorman.greet_customer("Alex");
|
||||||
|
doorman.greet_customer("John");
|
||||||
|
doorman.greet_customer("Jessie");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn greet_customers_closure(doorman: impl Fn(&str)) {
|
||||||
|
doorman("Bill");
|
||||||
|
doorman("Alex");
|
||||||
|
doorman("John");
|
||||||
|
doorman("Jessie");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let greeting = String::from("Hello! How are you");
|
||||||
|
|
||||||
|
// Method 1 for passing in functions with state.
|
||||||
|
// Just create a struct, store the state, and add a method.
|
||||||
|
// If you need to be generic, it can be a trait method.
|
||||||
|
let doorman = GreeterWithState {
|
||||||
|
greeting: &greeting,
|
||||||
|
};
|
||||||
|
greet_customers(doorman);
|
||||||
|
|
||||||
|
// Method 2 for passing in functions with state.
|
||||||
|
// Notice that the body of this closure is exactly the same
|
||||||
|
// as GreeterWithState's Doorman implementation.
|
||||||
|
//
|
||||||
|
// This makes things much cleaner with less clutter, but
|
||||||
|
// we are forgetting something very important.
|
||||||
|
greet_customers_closure(|customer_name| {
|
||||||
|
println!("{}, {}?", greeting, customer_name); // Capture greeting by reference
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in a new issue