3 ms·
> But Rust requires a closure there. You can't pass a pointer to a function. Actually, you can. fn perr(e: &str) { println!("There was an error :(
by bryal 11y ago
> But Rust requires a closure there. You can't pass a pointer to a function.
Actually, you can.
fn perr(e: &str) {
println!("There was an error :(, {}", e)
}
fn main() {
Err("ERROR").unwrap_or_else(perr);
}
The above code works, and can be run here: http://is.gd/2RCmG9 http://is.gd/2RCmG9
- Animats 11y agoAh. Thanks. I last tried this around Rust 1.0. Closures were still in flux back then.
- Manishearth 11y agoAh. Pre-1.0 we didn't have the Fn* traits. Closures were boxed (two closures with the same signature would have the same type due to this), and closures/functions were different types. You could declare an argument to be a closure or a function but not both. Post "unboxed closures", closures are now stored on the stack (thus they usually optimize away; for example if you use an iterator with a bunch of adapters like filter/map it will optimize down to a for loop). Each closure has a unique anonymous type (you can box them if you want them to have the same type), and all closures implement one or more of the Fn* traits, as do function pointers. So arguments can be generic over all callables, and you can pass in a closure or a function or your own custom callable.
- dbaupp 11y agoOnly `proc` closures were boxed, `|...| -> ...` closures were pointers into the stack. However, it is true that all closures were type erased, and were hence equivalent to certain trait object types (`Box<FnOnce(...) -> ...>` for `proc`, and `&mut FnMut(...) -> ...` for the pipes). Also, functions could coerce to either of the closure types, and hence be passed straight to functions expecting them.
- Manishearth 11y ago> Also, functions could coerce to either of the closure types Huh, I recall this not working. Perhaps I made a mistake then. > closures were pointers into the stack Ah, the type erasure was through &mut. TIL; I always thought it was Box only.
- owtM 11y agofn main() { Err("ERROR").unwrap_or_else(perr); } gross.