函数响应式编程概述

什么是编程?

函数响应式编程概述_第1张图片
范式概念
函数响应式编程概述_第2张图片
需求-模式-代码

面向过程 vs 面向对象

函数响应式编程概述_第3张图片
面向过程和面向对象

命令式编程 vs 函数式编程

函数响应式编程概述_第4张图片
命令式语言下的响应式编程

函数响应式编程概述_第5张图片
声明式编程

函数响应式编程

  • 满足函数式的一些特性
  • 面向离散事件流
  • 离散时间流操作

什么是ReactiveCocoa?

  • Github Mac客户端副产物
  • FRP在Cocoa框架下的实现
  • 富含了Cocoa框架多种组件
  • 提供基于时间变化的数据流的组合和实现
  • 简称RAC

理论基础

理解基于时间变化的数据流

函数响应式编程概述_第6张图片
  • 如何创建
  • 如何遍历
  • 如何停止遍历

基于时间变化的数据流可操作范围

函数响应式编程概述_第7张图片

更多操作

  • 加壳


    函数响应式编程概述_第8张图片

函数式编程四个特性

  • 闭包&高阶函数
  • 惰性计算
  • 不改变状态
  • 递归

核心组件

函数响应式编程概述_第9张图片

RACStream的两个子类

函数响应式编程概述_第10张图片

Sequence vs Signal

  • Pull-driver vs Push-driver
  • Data vs Event
  • 其他差异

RACSequence使用方法

函数响应式编程概述_第11张图片

RACSignal使用示例

函数响应式编程概述_第12张图片

Signal Subscriber Disposable

函数响应式编程概述_第13张图片

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);
}

你可能感兴趣的:(函数响应式编程概述)