加入收藏 | 设为首页 | 会员中心 | 我要投稿 晋中站长网 (https://www.0354zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 移动互联 > 评测 > 正文

手把手介绍函数式编程:从命令式重构到函数式

发布时间:2019-09-10 00:12:11 所属栏目:评测 来源:佚名
导读:本文是一篇手把手的函数式编程入门介绍,借助代码示例讲解细腻。但又不乏洞见,第一节中列举和点评了函数式种种让眼花缭乱的特质,给出了『理解函数式特质的指南针:函数式代码的核心特质就一条,无副作用』,相信这个指南针对于有积极学过挖过函数式的同

通过将代码片段打包到函数中,程序可以更具声明性。

  1. from random import random 
  2.  
  3. def move_cars(): 
  4.     for i, _ in enumerate(car_positions): 
  5.         if random() > 0.3: 
  6.             car_positions[i] += 1 
  7.  
  8. def draw_car(car_position): 
  9.     print '-' * car_position 
  10.  
  11. def run_step_of_race(): 
  12.     global time 
  13.     time -= 1 
  14.     move_cars() 
  15.  
  16. def draw(): 
  17.     print '' 
  18.     for car_position in car_positions: 
  19.         draw_car(car_position) 
  20.  
  21. time = 5 
  22. car_positions = [1, 1, 1] 
  23.  
  24. while time: 
  25.     run_step_of_race() 
  26.     draw() 

要理解这个程序,读者只需读一下主循环。『如果还剩下时间,请跑一步,然后画出线图。再次检查时间。』如果读者想要了解更多关于比赛步骤或画图的含义,可以阅读对应函数的代码。

没什么要再说明的了。 代码是自描述的。

拆分代码成函数是一种很好的、简单易行的方法,能使代码更具可读性。

这个技术使用函数,但将函数用作子例程( sub-routine ),用于打包代码。对照上文说的指南针,这样的代码并不是函数式的。实现中的函数使用了没有作为参数传递的状态,即通过更改外部变量而不是返回值来影响函数周围的代码。要确认函数真正做了什么,读者必须仔细阅读每一行。如果找到一个外部变量,必须反查它的源头,并检查其他哪些函数更改了这个变量。

消除状态

下面是赛车代码的函数式版本:

  1. from random import random 
  2.  
  3. def move_cars(car_positions): 
  4.     return map(lambda x: x + 1 if random() > 0.3 else x, 
  5.                car_positions) 
  6.  
  7. def output_car(car_position): 
  8.     return '-' * car_position 
  9.  
  10. def run_step_of_race(state): 
  11.     return {'time': state['time'] - 1, 
  12.             'car_positions': move_cars(state['car_positions'])} 
  13.  
  14. def draw(state): 
  15.     print '' 
  16.     print 'n'.join(map(output_car, state['car_positions'])) 
  17.  
  18. def race(state): 
  19.     draw(state) 
  20.     if state['time']: 
  21.         race(run_step_of_race(state)) 
  22.  
  23. race({'time': 5, 
  24.       'car_positions': [1, 1, 1]}) 

代码仍然是分解成函数。但这些函数是函数式的,有三个迹象表明这点:

  1. 不再有任何共享变量。 time 与 car_position 作为参数传入 race() 。
  2. 函数是有参数的。
  3. 在函数内部没有变量实例化。所有数据更改都使用返回值完成。基于 run_step_of_race() 的结果, race() 做递归调用。每当一个步骤生成一个新状态时,立即传递到下一步。

(编辑:晋中站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读