Crust of Rust: functions, closures, and their traits - My Notes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![feature(const_trait_impl, const_fn_trait_bound)] | |
fn main() { | |
println!("Howdy partner?"); | |
let mut x = bar::<i32>; | |
println!("{}", std::mem::size_of_val(&x)); | |
baz(bar::<u32>); | |
baz(bar::<i32>); | |
//quox(bar::<u32>); | |
make_fn()(); | |
let z = String::new(); | |
let f_nocapture = || { | |
//println!("{}", z); | |
}; | |
baz(f_nocapture); | |
let mut z = String::new(); | |
let f = || { | |
z.clear(); // Closure is `FnMut` as variable `z` is mutated here | |
}; | |
quox_fnmut(f); | |
let z = String::new(); | |
let f = || { | |
// To drop `z`, we need ownership. But we can only drop it once. | |
// Hence, the need for `FnOnce`. | |
drop(z); | |
}; | |
quox_fnonce(f); | |
// dyn Fn | |
let z = String::new(); | |
let f = || { | |
println!("{}", z); | |
}; | |
let f: Box<dyn FnMut()> = Box::new(f); | |
quox(f); | |
let x = || { | |
String::from("foo"); | |
}; | |
foo(x); | |
quox_forbound(|x| x); | |
} | |
// for bounds | |
fn quox_forbound<F>(f: F) | |
where | |
F: for<'a> Fn(&'a str) -> &'a str, // read as "For any lifetime 'a, F's implemention of 'a | |
// of a function from a str reference with a lifetime of a | |
// to another reference with the same lifetime of a. | |
{ | |
} | |
// const Fn | |
// Still under discussion RFC2632, requires nightly and enable features shown below: | |
// #![feature(const_trait_impl, const_fn_trait_bound)] | |
const fn foo<F: ~const FnOnce()>(f: F) { | |
f(); | |
} | |
// This should work later on once RFC2632 is finished. | |
// const fn test_foo() { | |
// let x = || { | |
// String::new(); // this should work as `String::new()` is a `const fn` | |
// }; | |
// foo(x); | |
// } | |
fn bar<T>() {} | |
// function item & function pointer | |
// there is no state | |
fn baz(f: fn()) { | |
println!("{}", std::mem::size_of_val(&f)); | |
} | |
// this is a trait & trait bound | |
fn quox<F>(f: F) | |
where | |
F: FnMut(), | |
{ | |
} | |
fn quox_fn<F>(f: &F) | |
where | |
F: Fn(), | |
{ | |
} | |
fn quox_fnmut<F>(f: F) | |
where | |
F: FnMut(), | |
{ | |
} | |
fn quox_fnonce<F>(f: F) | |
where | |
F: FnOnce(), | |
{ | |
} | |
fn make_fn() -> impl Fn() { | |
let z = String::from("hello"); | |
move || { | |
// need to specify `move` to force the closure to take ownership for `z`. | |
println!("Inside closure: {}", z); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment