Skip to content

Instantly share code, notes, and snippets.

@bsodmike
Created October 9, 2021 14:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bsodmike/8212fc2429930531126a2459c923a62d to your computer and use it in GitHub Desktop.
Save bsodmike/8212fc2429930531126a2459c923a62d to your computer and use it in GitHub Desktop.
Crust of Rust: functions, closures, and their traits - My Notes.
#![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