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
348 每月下载量
用于 20 个 crate(通过 serde_closure)
32KB
903 行代码(不含注释)
serde_closure
可序列化和可调试的闭包。
此库提供宏来封装闭包,使其可序列化和可调试。
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::FnOnce
、traits::FnMut
和 traits::Fn
,在夜间 Rust 中也实现了 std::ops::FnOnce
、std::ops::FnMut
和 std::ops::Fn
,使用 unboxed_closures
和 fn_traits
功能(rust issue #29625)。
- 有三个宏,分别是
FnOnce
、FnMut
和Fn
,对应于 Rust 中的三种闭包类型。 - 使用宏之一包装你的闭包,它现在将实现
Copy
、Clone
、PartialEq
、Eq
、Hash
、PartialOrd
、Ord
、Serialize
、Deserialize
和Debug
。 - 以下是一些小的语法限制,将在下面进行说明。
- 这个包有一个不可避免但已记录和合理的
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
闭包,捕获 hello
和 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!(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 License,版本 2.0,(LICENSE-APACHE.txt 或 https://apache.ac.cn/licenses/LICENSE-2.0)
- MIT 许可证 (LICENSE-MIT.txt 或 http://opensource.org/licenses/MIT)
自由选择。
除非您明确声明,否则根据Apache-2.0许可证定义,您有意提交以包含在作品中的任何贡献,应如上双授权,不附加任何其他条款或条件。
lib.rs
:
可序列化和可调试的闭包。
📦 Crates.io │ 📑 GitHub │ 💬 Chat
此库提供宏来封装闭包,使其可序列化和可调试。
请参阅 serde_closure
以获取文档。
依赖关系
~1.5MB
~36K SLoC