2个版本
0.1.1 | 2019年2月17日 |
---|---|
0.1.0 | 2019年2月16日 |
#939 in 数据结构
59KB
942 行
福罗普
一个为Rust设计的函数式响应式流库。
- 小型 (~20 个操作)
- 同步
- 无依赖
- 是 FRP (哈哈!)
基于André Staltz的JavaScript库 xstream 设计,该库很好地将响应式扩展 (Rx) 的概念简化到最基本的形式。
这个库并不是按照Conal Elliot的定义那样是 FRP (函数式响应式编程),而是一种既函数式又响应式的设计范式。 为什么我不能说FRP但我确实做到了。
示例
use froop::{Sink, Stream};
// A sink is an originator of events that form a stream.
let sink: Sink<u32> = Stream::sink();
// Map the even numbers to their square.
let stream: Stream<u32> = sink.stream()
.filter(|i| i % 2 == 0)
.map(|i| i * i);
// Print the result
stream.subscribe(|i| if let Some(i) = i {
println!("{}", i)
});
// Send numbers into the sink.
for i in 0..10 {
sink.update(i);
}
sink.end();
想法
函数式响应式编程是函数式编程 (FP) 的良好基础。逐步组合互锁操作的步骤是一种相对简单的方法,可以将FP结构应用于软件。
同步
处理作为时间值(或事件)的流的库通常将数据从A点移动到B点的概念与转换数据的算子混淆。结果是,库必须处理数据队列、队列长度和背压。
福罗普没有队列
将数据更新到操作树的每个 Sink::update()
都以同步方式执行。福罗普没有调度“稍后”的算子,即没有 delay()
或其他时间移位操作。
这也意味着福罗普也没有内部线程、future等。
线程安全
福罗普树中的每个部分都是线程安全的。您可以将在另一个线程中移动 Sink
,或订阅和传播在UI主线程上。调用 Sink::update()
的线程执行整个树。
安全是有代价的,froop不是一个零成本抽象库。树中的每一部分都受到互斥锁的保护。这对于大多数应用程序来说是可以的,因为无争用的锁在执行中不会造成太多开销。但是,如果您计划同时使用大量线程更新树中的许多值,您可能会因为锁争用而体验到性能下降。
不要碍事
Froop在使用时尽量减少认知负担。
- 每个操作符都是一个
FnMut(&T)
,使其尽可能易用。 - 操作符函数不需要
Sync
和/或Send
。 - Froop流实例本身是
Sync
和Send
。 - 对事件值
T
施加最小的约束。