[−][src]Crate serde_closure
Serializable closures.
This library provides macros to wrap closures such that they can be serialized and sent between other processes running the same binary.
fn sum_of_squares(input: &[i32]) -> i32 { input.dist_iter() .map(Fn!(|&i| i * i)) .sum() }
For example, if you have multiple forks of a process, or the same binary running on each of a cluster of machines, this library would help you to send closures between them.
This library aims to work in as simple and un-magical a way as possible. It
currently requires nightly Rust for the unboxed_closures
and fn_traits
features (rust issue
#29625).
- There are three macros,
FnOnce
,FnMut
andFn
, corresponding to the three types of Rust closure. - The captured variables, i.e. those variables that are referenced by the closure but are declared outside of it, must be explicitly listed.
- There are currently some minor limitations of syntax over normal closure syntax, which are documented below.
- The closure is coerced to a function pointer, which is wrapped by relative::Code such that it can safely be sent between processes.
Examples of wrapped closures
Inferred, non-capturing closure:
|a| a+1
FnMut!(|a| a+1)
Annotated, non-capturing closure:
|a: String| -> String { a.to_uppercase() }
FnMut!(|a: String| -> String { a.to_uppercase() })
Inferred closure, capturing num
:
let mut num = 0; |a| num += a
let mut num = 0; FnMut!([num] |a| *num += a)
Note: As this is a FnMut closure, num
is a mutable reference, and must be
dereferenced to use.
move
closure, capturing hello
and world
:
let hello = String::from("hello"); let mut world = String::new(); move |name| { world += (hello.to_uppercase() + name).as_str(); }
let hello = String::from("hello"); let mut world = String::new(); FnMut!([hello, world] move |name| { *world += (hello.to_uppercase() + name).as_str(); })
Note: world
must be dereferenced to use.
Cosmetic limitations
As visible above, there are currently some minor limitations:
- The captured variables in FnMut and Fn closures are references, so need to be dereferenced;
- Compiler errors are not as helpful as normal:
error[E0308]: mismatched types
...
= note: expected type `for<..> fn(&'r mut (..), (..))`
found type `[closure@<FnMut macros>:9:9: 10:44 my_var:_]`
means that my_var
is a captured variable, but was not explicitly listed.
Macros
Fn | Macro that wraps a closure, evaluating to a |
FnMut | Macro that wraps a closure, evaluating to a |
FnOnce | Macro that wraps a closure, evaluating to a |
Structs
Fn | A struct representing a serializable closure, created by the |
FnMut | A struct representing a serializable closure, created by the
|
FnOnce | A struct representing a serializable closure, created by the
|