函数响应式编程概述
2018-08-02 本文已影响63人
Jorunk
什么是编程?
范式概念 需求-模式-代码面向过程 vs 面向对象
面向过程和面向对象命令式编程 vs 函数式编程
命令式语言下的响应式编程声明式编程
函数响应式编程
- 满足函数式的一些特性
- 面向离散事件流
- 离散时间流操作
什么是ReactiveCocoa?
- Github Mac客户端副产物
- FRP在Cocoa框架下的实现
- 富含了Cocoa框架多种组件
- 提供基于时间变化的数据流的组合和实现
- 简称RAC
理论基础
理解基于时间变化的数据流
- 如何创建
- 如何遍历
- 如何停止遍历
基于时间变化的数据流可操作范围
更多操作
-
加壳
函数式编程四个特性
- 闭包&高阶函数
- 惰性计算
- 不改变状态
- 递归
核心组件
RACStream的两个子类
Sequence vs Signal
- Pull-driver vs Push-driver
- Data vs Event
- 其他差异
RACSequence使用方法
RACSignal使用示例
Signal Subscriber Disposable
Scheduler
- 用来做调度
- 代替GCD
- 异步和并发
Cocoa框架适配工具
作业
一、判断题:
- (1)函数式编程是面向对象编程的升级版
错。函数式编程和链式编程相对应,所以说并不是升级版,而是不同的编程范式;编程的思想或者模式是根据需求来的,既然是根据需求来的就不存在升级或者降级。
- (2)组成链式调用的必要条件就是在方法里面返回对象自己
错。只要返回的是相同的类型的对象就可以,未必要是自己,也返回子类或者其他类,只要这个链式调用可以承载下去。 - (3)响应式编程可以用C语言这样的语言实现
对 - (4)ReactiveCocoa是基于KVO的一个开源库
错。虽然有些信号的产生来自KVO,但是有些不是 - (5)ReactiveCocoa是一个纯函数式编程的库
错。ReactiveCocoa不是一个纯函数式编程的库,因为它本身没有建立在纯函数式的环境 - (6)下面的函数由于有赋值所以不是一个纯函数
typedef int(^FunctionType1)(int x);
typedef int(^FunctionType2)(int x, int y);
FunctionType1 someFunction(FunctionType2 func, int x, FunctionType1 valueMap) {
int nextValue = valueMap(x);
return ^int(int y) {
return func(nextValue, y);
};
}
虽然有赋值,但是每次固定输入都能得到固定的输出,并且没有改变外部的状态,是纯函数。
二、问答题:
- (1)Pull-driver和Push-driver的区别?
没故事的卓同学
想到了master,slave这个经典的场景。一个黑心的老板有5个程序员,这里有100个需求。每个程序员完成后,告诉老板说我做完了,再来一个需求。这就是pull driver,接收方主动来拿。如果老板不管这个人忙不忙,需求来了就直接分配给某个程序员,这就是push driver,源直接推送给某个接收方
- (2)怎么理解函数式语言中的引用透明?
引用透明(Referential transparency),指的是函数的运行不依赖于外部变量或"状态",只依赖于输入的参数,任何时候只要参数相同,引用函数所得到的返回值总是相同的。
引用透明(Referential Transparent)的概念与函数的副作用相关,且受其影响。如果程序中任意两处具有相同输入值的函数调用能够互相置换,而不影响程序的动作,那么该程序就具有引用透明性。它的优点是比非引用透明的语言的语义更容易理解,不那么晦涩。纯函数式语言没有变量,所以它们都具有引用透明性。
- (3)函数式语言主张不变量的原因是什么?
- 保证和数学模型的亲密性
- 解决了线程的安全
- 让编译器更好的优化
其次通过声明区分可变和不可变性降低了复杂度。我们可以更加关注变化的value,增加了一种语义。当我们看到一个值声明是可变的,我们会知道这个值在后面的代码中会被赋值。
三、编程题:
- (1)基于变量不可变(任何变量不允许二次赋值)来实现一个计算最大值的函数,定义如下
int max(int *array, int count)
int max(int *array, int count){
if (count < 1) return INT_MIN;
if (count == 1) return array[0];
int headMax = max(array, count - 1);
return headMax > array[count - 1] ? headMax : array[count - 1];
}
- (2)自由发挥写一个高阶函数应用的例子,要求必须有返回函数的部分
int array[] = {1, 2, 3, 4, 8, -1};
int max = fold(array, sizeof(array) / sizeof(typeof(array)), ^int(int acc, int next) {
return acc > next ? acc : next;
}, INT_MIN);
int fold(int *array, int count, ReduceType block,int first){
if (count == 0) return first;
return fold(array + 1, count - 1, block, block(first, array[0]));
}
typedef BOOL (^ConditionType)(int a);
int find(int *array, int count, ConditionType finder)
{
if (count == 0) return INT_MIN;
if (finder(array[0])) {
return array[0];
}
return find(array + 1, count - 1, finder);
}
ConditionType not(ConditionType block)
{
return ^BOOL(int a){
return !block(a);
};
}
main(){
ConditionType even = ^BOOL(int v){
return v % 2 ==0;
};
int value = find(array, sizeof(array) / sizeof(int), even);
}