serialization - 我可以序列化 Vec 的闭包吗然后反序列化并执行它?
问题描述
我想做这样的伪代码:
let mut vec = Vec<u8>::new();
vec.resize(1024); // Some large-enough size
serialize(&vec, || { .... });
// ... other code blah blah ...
deserialize(&vec); // This will execute the closure
理想情况下,我将能够在另一个线程中运行反序列化,这就是这样做的真正意义所在。
我不想发送操作码和数据,因为这种方式打开了一个非常干净的编程模型,您无需创建消息并发送它们。相反,您只需在另一个线程中运行任意复杂的代码。
为什么“非常干净”?
没有需要创建的操作码(消息)。即,更少的代码。
接收端没有用于操作码调度的 switch 语句。即,更少的代码。
由于没有协议,因此无需对消息进行版本控制。即,更少的代码。
这个想法不能跨进程使用,但这对我的需要来说是可以的。
解决方案
不使用unsafe
? 不不不不。
问题是,由于Vec<u8>
s 可以被简单地修改,你很容易违反 Rust 的安全不变量。考虑以下代码:
let vec = Vec<u8>::new();
vec.resize(1024);
// Our theoretical serialize function.
serialize(&vec, || { /* ... */ });
vec[0] = 0x90; // What happens to the closure now?
deserialize(&vec); // There goes any memory safety...
但是,如果您只想在线程之间发送闭包,请考虑使用类似的东西std::sync::mpsc
,它支持发送闭包:
use std::thread;
use std::sync::mpsc::channel;
let (tx, rx) = channel();
thread::spawn(move || {
tx.send(|| { "hi" }).unwrap();
});
let f = rx.recv().unwrap();
assert_eq!(f(), "hi");
但是,我的猜测是,这实际上不是您想要做的。就像 Netwave 在评论中所说的那样,您很可能实际上想要发送数据和操作的标签;例如:
// On one thread...
tx.send((Op::REMOVE_FILE, path));
// and on the other thread...
let (op, path) = rx.recv();
match op {
Op::REMOVE_FILE => remove_file(path),
/* ... */
}
推荐阅读
- javascript - 按钮 onclick 有重定向问题
- solr - Grafana 不会显示 Solr 指标
- r - 将多个列表合并到 ggpot2 的数据框中
- c - 可以通过将变量标记为 volatile 来修复不安全的类型双关语吗?
- reactjs - Apollo 中具有本地状态的变量返回数据
- tcp - tcp接收数据中断
- mysql - ubuntu mysql 5.7 /var/run/mysqld/mysqld.sock?
- laravel - 如何在 Ubuntu 16.04 上使用 Apache 使用 SSL 实现 Laravel Websockets(beyondco.de 的演示项目)?
- html - 每次我单击“href”链接时,它都会再次将该链接添加到 URL。为什么?
- indexing - Microsoft T-SQL 不支持多个主键;建议的解决方法?