#closures #distributed #serde #serialization

serde_closure_derive

可序列化和可调试的闭包。此库提供宏来封装闭包,使其可序列化和可调试。请参阅 https://crates.io/crates/serde_closure 以获取文档

19 个版本

0.3.3 2022 年 11 月 24 日
0.3.2 2020 年 8 月 5 日
0.3.1 2020 年 7 月 14 日
0.2.10 2020 年 2 月 5 日
0.2.9 2019 年 11 月 22 日

#149 in #closures

Download history 131/week @ 2024-04-25 142/week @ 2024-05-02 112/week @ 2024-05-09 124/week @ 2024-05-16 114/week @ 2024-05-23 139/week @ 2024-05-30 75/week @ 2024-06-06 88/week @ 2024-06-13 118/week @ 2024-06-20 57/week @ 2024-06-27 53/week @ 2024-07-04 77/week @ 2024-07-11 88/week @ 2024-07-18 88/week @ 2024-07-25 85/week @ 2024-08-01 70/week @ 2024-08-08

348 每月下载量
用于 20 个 crate(通过 serde_closure

MIT/Apache 许可

32KB
903 行代码(不含注释)

serde_closure

Crates.io MIT / Apache 2.0 licensed Build Status

📖 文档 | 💬 聊天

可序列化和可调试的闭包。

此库提供宏来封装闭包,使其可序列化和可调试。

use serde_closure::{traits::Fn, Fn};

let one = 1;
let plus_one = Fn!(|x: i32| x + one);

assert_eq!(2, plus_one.call((1,))); // this works on stable and nightly
// assert_eq!(2, plus_one(1));      // this only works on nightly
println!("{:#?}", plus_one);

// prints:
// Fn<main::{{closure}} at main.rs:6:15> {
//     one: 1,
//     source: "| x : i32 | x + one",
// }

此库旨在尽可能简单和安全地工作。在稳定 Rust 中,封装的闭包实现了 traits::FnOncetraits::FnMuttraits::Fn,在夜间 Rust 中也实现了 std::ops::FnOncestd::ops::FnMutstd::ops::Fn,使用 unboxed_closuresfn_traits 功能(rust issue #29625)。

  • 有三个宏,分别是 FnOnceFnMutFn,对应于 Rust 中的三种闭包类型。
  • 使用宏之一包装你的闭包,它现在将实现 CopyClonePartialEqEqHashPartialOrdOrdSerializeDeserializeDebug
  • 以下是一些小的语法限制,将在下面进行说明。
  • 这个包有一个不可避免但已记录和合理的 unsafe 使用。

包装闭包的示例

推断的、非捕获闭包

|a| a+1
FnMut!(|a| a+1)

注释的、非捕获闭包

|a: String| -> String { a.to_uppercase() }
FnMut!(|a: String| -> String { a.to_uppercase() })

推断的闭包,捕获 num

let mut num = 0;
|a| num += a
let mut num = 0;
FnMut!(|a| num += a)

move 闭包,捕获 helloworld

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!(move |name| {
    world += (hello.to_uppercase() + name).as_str();
})

限制

目前有一些小的限制

  • 以小写字母开头的类型可能需要与变量区分。如果您看到以下错误,请修改类型的字母大小写,或添加 my_struct::<> 以区分。
error[E0308]: mismatched types
   --> tests/test.rs:450:4
    |
449 |       FnOnce!(move || {
    |  _____-
450 | |         my_struct;
    | |         ^^^^^^^^^ expected struct `serde_closure::internal::a_variable`, found struct `my_struct`
451 | |     });
    | |______- in this macro invocation
    |
    = note: expected type `serde_closure::internal::a_variable`
               found type `my_struct`
  • 以大写字母开头的变量可能需要与类型区分。如果您看到以下错误,请修改变量的字母大小写,或将其包裹在 (MyVariable) 中以区分。
error: imports cannot refer to local variables
   --> tests/test.rs:422:3
    |
417 |       FnOnce!(move || {
    |  _____-
418 | |         MyVariable;
    | |         ^^^^^^^^^^
419 | |     });
    | |______- in this macro invocation
    |
  • 闭包内部调用的函数和闭包可能需要区分。这可以通过与上述方法相同的方式完成,即使用 function::<> 对函数和 (closure) 对闭包进行区分。

进程间序列化

此包创建的闭包是不可命名的——也就是说,就像普通的闭包一样,没有 Rust 语法可以用来编写类型。这意味着要反序列化闭包,您需要指定您正在反序列化的确切类型,而不命名它(这是可能的,但不是很实用),或者通过将类型存储在 trait object 中来 擦除 类型。

serde_traitobject 包允许 trait objects 在运行相同二进制文件的其他进程之间安全地序列化和发送。

例如,如果您有多个进程分支,或者每个集群上的同一二进制文件都在运行,serde_traitobject 将帮助您在这些进程之间发送可序列化的闭包。这可以通过将闭包向上转换为 Box<dyn serde_traitobject::Fn()> 来完成,这是自动可序列化和反序列化的,并且与 serde 一起。

许可证

根据您选择以下任一许可证

自由选择。

除非您明确声明,否则根据Apache-2.0许可证定义,您有意提交以包含在作品中的任何贡献,应如上双授权,不附加任何其他条款或条件。


lib.rs:

可序列化和可调试的闭包。

📦  Crates.io  │  📑  GitHub  │  💬  Chat

此库提供宏来封装闭包,使其可序列化和可调试。

请参阅 serde_closure 以获取文档。

依赖关系

~1.5MB
~36K SLoC