为什么80%的码农都做不了架构师?>>>   

#递归

1. 递归中的环
2. 归约和映射算法

#递归中的环

由于恒定性,Elixir中的环(与其他函数式编程语言一样)和命令式语言中的写法是不同的。例如,C语言中的写法是这样的:

for(i = 0; i < sizeof(array); i++) {array[i] = array[i] * 2;
}

上述例子中,我们更改了数组和变量i。在Elixir中是不可更改的。所以函数式语言中以递归来替代:一个函数被反复调用,直到情况达到停止条件。在这个进程中没有数据被改变。思考下面的例子,一个字符串被打印任意次:

defmodule Recursion dodef print_multiple_times(msg, n) when n <= 1 doIO.puts msgenddef print_multiple_times(msg, n) doIO.puts msgprint_multiple_times(msg, n - 1)end
endRecursion.print_multiple_times("Hello!", 3)
# Hello!
# Hello!
# Hello!

case类似,一个函数可以拥有许多从句。当传递来的参数与从句的参数模式相匹配并且其卫语句返回值为真,那么特定的从句就会被执行。

在上述例子中,当第一次调用print_multiple_times/2时,变量n等于3

第一个从句的守卫说道“当且仅当n小于或等于1时使用这个定义”。由于不符合这个情形,Elixir继续到下一个从句定义。

第二个定义匹配模式成功,并且没有守卫,所以被执行了。它先打印了我们的msg然后调用了他自己并传递了参数n-1 (2)

我们的msg再次被打印,print_multiple_times/2也再次被调用,这一次第二个参数被设置成了1。由于n已经被设置成1了,print_multiple_times/2的第一个定义中的卫语句执行结果为真,所以我们执行了这个定义。msg被打印同时没有额外的语句需要执行了。

我们这样定义print_multiple_times/2,无论第二个参数是什么数字,它不是触发了我们的第一个定义(被称为基本案例),就是触发了我们的第二个定义,并向基本案例更近了一步。

#归约和映射算法

让我们看看如何利用递归的力量来计算一个列表的数字之和:

defmodule Math dodef sum_list([head | tail], accumulator) dosum_list(tail, head + accumulator)enddef sum_list([], accumulator) doaccumulatorend
endIO.puts Math.sum_list([1, 2, 3], 0) #=> 6

我们以列表[1, 2, 3]和初始值0为参数调用了sum_list。我们将逐个尝试从句,直到模式匹配成功。这个案例中,列表[1 ,2, 3]匹配了[head | tail]head对应着1tail对应着[2, 3]accumulator设置成0

接着,我们将列表的头与收集器相加head + accumulator,并将列表的尾作为第一个参数再次调用sum_list。尾会再次匹配[head | tail]直到列表变空:

sum_list [1, 2, 3], 0
sum_list [2, 3], 1
sum_list [3], 3
sum_list [], 6

当列表为空时,将匹配最后的从句,返回最终结果6

将一个列表归约成一个值的过程叫做归约算法,它是函数式编程的中心。

如果我们想将列表中所有值翻倍呢?

defmodule Math dodef double_each([head | tail]) do[head * 2 | double_each(tail)]enddef double_each([]) do[]end
end
iex math.exs
iex> Math.double_each([1, 2, 3]) #=> [2, 4, 6]

这里我们使用递归来遍历列表,将每个元素翻倍并返回一个新的列表。将一个列表映射到一个新列表的过程叫做映射算法。

递归和尾调用是Elixir中的重要部分,且常用于创建环。然而在实际使用Elixir时,你很少会像上面那样用递归来操作列表。

下一章我们将看到的Enum模块,已经提供了许多用于操作列表的便捷方法。实际中,上述例子可以写成:

iex> Enum.reduce([1, 2, 3], 0, fn(x, acc) -> x + acc end)
6
iex> Enum.map([1, 2, 3], fn(x) -> x * 2 end)
[2, 4, 6]

或者使用捕获语法:

iex> Enum.reduce([1, 2, 3], 0, &+/2)
6
iex> Enum.map([1, 2, 3], &(&1 * 2))
[2, 4, 6]

让我们进一步观察Enumerable以及它懒惰的相对物Stream

转载于:https://my.oschina.net/ljzn/blog/726764

elixir官方入门教程 递归相关推荐

  1. elixir官方入门教程 模式匹配

    为什么80%的码农都做不了架构师?>>>    #模式匹配 1. 匹配操作符 2. 模式匹配 3. 标记操作符 在本章,我们将展示在Elixir中=号实际上是匹配操作符,以及如何使用 ...

  2. AFNnetworking快速教程,官方入门教程译

    AFNnetworking快速教程,官方入门教程译 分类: IOS2013-12-15 20:29 12489人阅读 评论(5) 收藏 举报 afnetworkingjsonios入门教程快速教程 A ...

  3. Unity游戏开发官方入门教程:飞机大战(六)——创建子弹

    Unity版本:Unity 2018.2.14f1 原视频链接:https://unity3d.com/cn/learn/tutorials/s/space-shooter-tutorial 教程目录 ...

  4. 第三章 Python Kivy 学习 -- Kivy官方入门教程Pong Game

    系列文章目录 第一章 Python Kivy 学习 – Kivy介绍及环境安装 第二章 Python Kivy 学习 – Kivy项目开发原理(待编辑) 第三章 Python Kivy 学习 – Ki ...

  5. Unity游戏开发官方入门教程:飞机大战(二)——创建飞船对象

    Unity版本:Unity 2018.2.14f1 原视频链接:https://unity3d.com/cn/learn/tutorials/s/space-shooter-tutorial 教程目录 ...

  6. 用TypeScript来写React官方入门教程 .tsx后缀文件,同时入门typescript和React

    用TypeScript来写React官方入门教程 .tsx后缀文件,同时入门typescript和React 1. 项目说明: 这是React官网上那个下井字棋的入门教程,但是我把它换了typesci ...

  7. Unity游戏开发官方入门教程:飞机大战(五)——实现飞船控制脚本

    Unity版本:Unity 2018.2.14f1 原视频链接:https://unity3d.com/cn/learn/tutorials/s/space-shooter-tutorial 教程目录 ...

  8. snap7使用说明中文版_Python官方入门教程_中文版_3.7.3

    张小森:Python官方入门教程/2. 使用 Python 解释器​zhuanlan.zhihu.com 张小森:Python官方入门教程_中文版_3. Python 的非正式介绍​zhuanlan. ...

  9. Fragstats官方入门教程3 批处理多个栅格

    原著:Kevin McGarigal 翻译:地理时政志(公众号.CSDN同名,知乎:Jarviski) 在教程3中,将会教读者如何使用Fragstats完成批处理多个栅格,以及其他要注意的问题 以下原 ...

最新文章

  1. 利用链式存储结构实现线性表
  2. spark(一) build
  3. RocketMQ高性能之底层存储设计
  4. 使用verilog设计实现QR分解
  5. Spring Data JPA 从入门到精通~@Modifying修改查询
  6. 计算机结构介绍,计算机系统结构介绍.pdf
  7. 【LeetCode】【数组】题号:*54,螺旋数组
  8. HihoCoder-1523(思维)
  9. solidworks图纸模板添加_solidworks工程图模板如何设置和替换?
  10. word插入页码问题解决办法
  11. 印度市场救不了苹果手机,也救不了库克
  12. Java虚拟机 - JVM是什么?
  13. php 会员 开源,会员组_POSCMS_PHP开源_迅睿CMS系统
  14. C#开发基于ESMTP协议的邮件发送系统经验总结
  15. Exp 8 Web基础 20164318 毛瀚逸
  16. Qt学习笔记——获取本机网络信息(IP, 子网掩码, 广播地址,主机名
  17. 苹果三代耳机_苹果三代蓝牙无线耳机
  18. 泰坦x 和泰坦black 性能分析
  19. 大数据24小时:金山云再获2.2亿美元融资,马云12亿美元收购美企计划宣布告吹
  20. .NET Core 文件上传、下载、文件流转换

热门文章

  1. Shell解析curl返回的json数据
  2. 最终,我还是放弃了字节50W开发offer,选择了测试开发……
  3. mysql did not start_mysql 服务无法启动
  4. php 数组 闭包,PHP如何用array_filter加闭包函数过滤数组?
  5. 写论文中所需的EndNote x9下载、安装以及与wps相关联教程
  6. 5.2 - Function Basics
  7. vs2008下配置OGREV1.7源码
  8. vector和string
  9. linux v4l2 示例程序,linux驱动由浅入深系列:camera驱动之二(基于高通平台的V4L2结构及代码分析)...
  10. python怎么引入thrift文件_python使用thrift教程的方法示例