Scala讲座:编程的思考方法

开发 后端
本文继续Scala讲座的第三部分内容,即编程的思考方法,希望大家喜欢。

这篇是Scala讲座第七篇的第三部分,总括了函数式编程的思考方法。

在进行什么编程的时候,你用什么方法来思考呢?用命令是方法来考虑的话,一定是考虑“首先有一个变量,然后一边循环一边判断一下这样的条件,接着进行这种操作···”这样的操作步骤吧。

面向对象式方法来考虑时,一定是先考虑“程序中出现的这个对象里有什么东西(数据)呀?”,然后再给对象分配 “动作”(方法)吧。整体印象应该是,“对象”们互相分配好自己的工作,对象自己只做自己的工作其他的工作交给其他对象来完成,“对象”们互相合作来完成一个处理吧。即使是面向对象的情况下,对于一般语言来说,对象方法内也是用命令方式来实现的。

那么,函数式编程该是怎样的景象呢?函数式编程是“将函数应用在值或者对象上”这种思考方法,也就是函数只是将值或者对象转换成不同的别的东西。这样说,可能函数式方法还是很难在读者脑中浮现,那么就以“命令型”和“函数式”两种类型的例子为基础进行阐述吧。

[Scala讲座]题目:架子上的苹果

题目内容为模拟“架子上有100个苹果,一个个剥皮吃掉***一个也没有了。“这个过程。运行结果的样子因该如下所示:

  1. > scala AppleCounter  
  2. 99 apples on the wall.  
  3. 98 apples on the wall.  
  4. :  
  5. 2 apples on the wall.  
  6. 1 apple on the wall.  
  7. no apple on the wall. 
当苹果只有1或0个的时候,由于不是复数情况,所以处理方法有所不同。先用命令方式来实现一下。
  1. object AppleCounter{  
  2. def main(args:Array[String]):Unit = {  
  3. var appleList:List[String] = List()  
  4. for(i <- 1 to 100) {  
  5. var counter = 100 -i  
  6. if (counter == 1) appleList = appleList ::: List("1 apple on the wall.")  
  7. if (counter == 0) appleList = appleList ::: List("no apple on the wall.")  
  8. if (counter != 1 && counter != 0)  
  9. appleList = appleList ::: List(counter + " apples on the wall.")  
  10. }  
  11. appleList.foreach(x => println(x))  
  12. }  
首先准备好列表变量appleList,接着做100次循环。循环中用变量counter来存放当前所剩的苹果数,并根据该数字向例表末尾加入描述文本,其中对于1个和0个的情况进行特殊处理。***使用appleList的foreach方法对每一列表成员进行打印操作。题外话,由于Scala是函数式+面向对象语言,所以能够以这种命令式方法来编程,这对于不熟悉函数式编程的用户来说也还真不错。
好了,这次用函数式的方法来重新实现一下同样的逻辑。那么该怎样考虑函数式的实现呢?下面是实现例子。
  1. object AppleCounter {  
  2. def main(args:Array[String]):Unit = {val appleList = (0 until 100).reverse.map(x => x match {  
  3. case 1 => "1 apple on the wall." 
  4. case 0 => "no apple on the wall." 
  5. case _ => x + " apples on the wall." 
  6. })  
  7. appleList.foreach(x => println(x))  
  8. }  
这里不是想说明“程序短了不少啊···”,而是希望大家明白思考方法的不同之处(不过这里并没有声明变量appleList的类型,能够进行如此复杂的类型推断也真是挺厉害的呀!)。编写这段程序的时候,我一开始就没有考虑到循环这个概念。比起循环,我考虑的是如何将函数用在数字列表变量上。首先不是逻辑,而是创建用于执行函数的对象(这里是数字列表),然后考虑选择哪种函数来执行。
首先考虑创建如下的列表对象。
  1. List(999897, .... 210
这个通过(0 until 100).reverse部分来实现。接着对于这个列表的一个个数字,考虑返回数字相对应字符串的函数。对应部分如下
  1. (上面的列表).map(x => x match {  
  2. case 1 => "1 apple on the wall." 
  3. case 0 => "no apple on the wall." 
  4. case _ => x + " apples on the wall." 
  5. }) 
用Scala进行像样的函数式编程时,map是最重要的函数之一。也就是,对于列表中的每个元素用map函数传进来的函数执行一下,然后返回他的结果列表。这里传递给map函数的参数(函数对象)内容是:对于1返回1 apple on the wall.;对于0返回no apple on the wall;其他情况比如22,返回22 apples on the wall。根据该内容,map函数返回如下列表
  1. List("99 apples on the wall.""98 apples on the wall.", …"no apple on the wall."

***一行类似于命令式编程,对于例表appleList用foreach方法循环遍历,并用foreach传进的函数打印列表所有的元素,然后程序结束。
函数map不仅在List类中有,其他很多类中也有。

Scala讲座 图:map函数概念图

Scala讲座 图:map函数概念图 

函数式语言中List具有强大的功能,这里再一次强调,函数式编程不是考虑如何循环,而是首先考虑创建作为操作源的列表,然后考虑将怎样的函数适用于列表中的元素。由于使用如此风格的编程方式,所以就不需要保存用于循环的计数器呀,临时变量什么的了。

Scala讲座到这里,第七篇第三部分内容就结束了。

【编辑推荐】

  1. 万物皆对象:介绍Scala对象
  2. Scala的泛型:***大的特性
  3. Scala的Trait:可以包含代码的接口
  4. Scala的模式匹配和条件类
  5. Scala类:复数类,无参方法,继承和覆盖
责任编辑:book05 来源: JavaEye博客
相关推荐

2009-09-27 15:23:00

Scala讲座函数式编程Scala

2009-12-11 10:44:00

Scala讲座函数 scala

2009-09-24 09:28:00

Scala讲座全局变量scala

2009-08-27 10:06:15

Scala的构造方法

2009-12-11 10:42:00

Scala讲座类定义构造函数

2009-12-11 10:45:00

Scala讲座类型系统功能

2010-09-14 15:34:41

Scala

2009-09-27 15:29:00

Scala讲座面向对象Scala

2009-12-11 10:43:00

Scala讲座混入多重继承类型层次

2009-12-11 10:43:00

Scala讲座操作符函数

2010-11-17 11:31:22

Scala基础面向对象Scala

2013-08-20 09:23:06

Scala递归

2010-09-14 13:22:17

Scala编程指南Scala

2013-09-12 15:51:04

编程文化垃圾代码移动开发

2013-11-11 09:26:50

编程思考

2009-07-21 12:18:37

ScalaRational对象toString

2009-09-24 09:38:00

Scala讲座第一类对象scala

2010-07-26 08:35:06

ScalaJava

2009-02-06 09:08:04

Scala函数语言轻量级

2013-04-18 09:29:02

编程语言编程
点赞
收藏

51CTO技术栈公众号