🧩 附章 函数式语言是怎样工作的
📄 一句话概括

同一需求两版:类版 1 个可变状态、函数版 0 个,结果都是 378.0——面向对象管【谁】和【状态】,函数式管【怎么变】,真实系统两者并用。

📝 本节和前面几节的关系

A.13 说完课题,这一节回到全书主线:这两个范式不是对手,是分工。

一、实测:两版结果一样

类版:Cart 三个方法(add/total/init),可变状态 1 个(self.items)。 函数版:一个纯函数,可变状态 0 个,结果也是 378.0。 结果一致说明它不是【谁更强】的比赛。 类版多出来的是【谁在改它】——身份与责任。

二、分工在哪

面向对象管【谁】:这个购物车属于谁、谁能改它、改完通知谁。 函数式管【怎么变】:一份数据进来,算出另一份数据出去,中间不留痕。 所以两者能合起来用:对象持有状态,方法内部用纯函数做变换。 这也是今天主流语言的默认形态。

三、判断该用哪个

有身份、有生命周期、要记住上一步 → 对象。 只是把 A 变成 B、算完就完 → 纯函数。 判断依据一句话:这东西需要【记得住】吗? 需要就是对象。

四、动手 Demo:函数式语言和面向对象的关系

同一需求(购物车打折)写类版与函数版。 比较可变状态个数与结果。

class Cart:
    def __init__(self):
        self.items = []
    def add(self, p):
        self.items.append(p)
    def total(self):
        return sum(p for p in self.items if p > 100) * 0.9

def fp_total(items):
    return sum(p for p in items if p > 100) * 0.9

c = Cart()
for p in [50, 120, 300]:
    c.add(p)

print(c.total(), fp_total([50, 120, 300]))   # 378.0 378.0
print(len(c.items))                         # 3(对象记住了)

实跑输出:

--------------------------------------------------------------------
函数式语言和面向对象的关系
--------------------------------------------------------------------

  同一需求(购物车打折算总价)两版,**量行数与可变状态个数:**

  写法       结构              可变状态     结果
  ------------------------------------------------
  类版       Cart 三个方法     1            378.0
  函数版     一个纯函数        0            378.0

      两版结果一致                True
      类版可变状态                self.items(会被 add 改)
      函数版可变状态              0 个(只读入参、返回新值)
      类版多出来的东西            【谁】在改它(身份与责任)

  **注意两版结果一样**——**这说明它不是【谁更强的比赛】,是分工。**
  **面向对象管【谁】和【状态】**:这个购物车属于谁、谁能改它、改完通知谁。
  **函数式管【怎么变】**:一份数据进来,算出另一份数据出去,中间不留痕。
  **所以真实系统里两者并用**:**对象持有状态,方法内部用纯函数做变换。**

实测:类版 1 个可变状态、函数版 0 个,结果都是 378.0。 面向对象管【谁】和状态,函数式管【怎么变】。 真实系统的默认形态是两者并用:对象持状态,方法内部用纯函数做变换。

30 秒实验

  1. 挑一个你的类,把其中一个方法内部的循环改成推导式或纯函数。
  2. 判断这个类该不该保留——它需要【记得住】吗?

常见误区

  1. 把两个范式当对手。它们解决的是两个不同问题。
  2. 为了纯,把需要记住的状态也塞进参数里传来传去。那是自找麻烦。
自测三问(点开对答案) 1. 两版结果一样说明什么? —— 说明不是谁更强的比赛,而是分工:一个管状态,一个管变换。 2. 两者的分工怎么分? —— 面向对象管谁和状态,函数式管怎么变。 3. 判断用哪个的一句话? —— 这东西需要记得住吗?需要就是对象。

相关笔记