Scala学习:简化客户代码

开发 后端
本文节选自Martin Odersky,Lex Spoon和Bill Venners所著,Regular翻译的《Programming in Scala》的第九章。Scala是一种针对 JVM 将函数和面向对象技术组合在一起的编程语言。

9.2 前一个例子演示了高阶函数能在你实现API的时候帮助减少代码重复。高阶函数的另一个重要应用是把它们放在API里使客户代码更简洁。Scala的集合类型的特定用途循环方法提供了一个很好的例子。这些特定用途循环方法被定义在特质Iterable中,被List,Set,Array,还有Map扩展。很多已经在第三章的表格3.1中列了出来。不过现在请注意其中的一个例子来看看为什么这些方法如此有用。

51CTO编辑推荐:Scala编程语言专题

考虑exists,一个判断传入的值是否包含在集合中的方法。当然你也可以初始化一个var为假,循环遍历集合类型,检查每个元素,并且如果你找到了要寻找的就把var设置为真,通过这样的方式寻找元素。以下是使用了这种方式的方法去判断是否传入的List包含了负数的例子:

  1. def containsNeg(nums: List[Int]): Boolean = {  
  2.  var exists = false 
  3.  for (num < - nums)  
  4.   if (num <  0)  
  5.    exists = true 
  6.  exists  
  7. }  
假如你在解释器里定义了这个方法,你就可以这样调用:

  1. scala> containsNeg(List(1234))  
  2. res0: Boolean = false 
  3. scala> containsNeg(List(123, -4))  
  4. res1: Boolean = true 
不过更简洁的定义这个方法的方式是通过在传入的List上调用高阶函数exists,如:

  1. def containsNeg(nums: List[Int]) = nums.exists(_ <  0)  
这个版本的containsNeg能产生和前面的那个一样的结果:

  1. scala> containsNeg(Nil)  
  2. res2: Boolean = false 
  3. scala> containsNeg(List(01, -2))  
  4. res3: Boolean = true 
exists方法代表了控制抽象。是Scala库提供的特定用途循环架构而不是像while或for那样内建在Scala语言里的。上节中,高阶函数,filesMatching在对象FileMatcher的实现中减少了代码重复。exists方法提供了类似的好处,但因为exists是公开在Scala的集合类型API里的,所以它减少的是API的客户代码中的重复。exists不存在的话,如果你想要写一个containsOdd方法,检测列表是否包含了奇数,你或许会写成这样:

  1. def containsOdd(nums: List[Int]): Boolean = {  
  2.  var exists = false 
  3.  for (num < - nums)  
  4.   if (num % 2 == 1)  
  5.    exists = true 
  6.  exists  
  7. }  
若你比较了containsNeg和containsOdd的函数体,你会发现除了if表达式之外,其它东西都是重复的。使用exists,你就可以这么写:

  1. def containsOdd(nums: List[Int]) = nums.exists(_ % 2 == 1
这个版本的代码体再一次与相应的containsNeg方法的保持一致(使用了exists的版本),除了搜索的条件不同。然而代码重复的量却少得多,因为所有的循环架构都被提取成exists方法本身了。

Scala的标准库中还有许多其他循环方法。如果你能发现使用它们的机会,那么像exists一样,它们经常能缩短你的代码。

【相关阅读】

  1. 减少Scala中的代码重复
  2. Scala:尾递归的跟踪调用及其局限
  3. Scala允许的重复参数
  4. 学习Scala的闭包
  5. Scala的偏应用函数

责任编辑:book05 来源: Artima
相关推荐

2009-02-05 17:28:01

ScalaFriendFeedXML

2009-06-22 14:26:12

ScalaXML对象

2010-08-23 10:59:02

SAP金融服务CRM

2009-11-16 17:04:46

Inside Scal

2017-04-19 08:47:42

AsyncJavascript异步代码

2021-03-10 09:20:31

await代码前端

2009-07-21 16:58:31

Scala变量范围

2009-07-22 07:43:00

Scala闭包

2009-07-22 07:45:00

Scala代码重复

2009-09-28 11:42:21

KestrelScala

2011-05-07 14:53:49

2009-07-06 15:20:30

JSP表达式

2009-07-22 09:02:45

Scala组合继承

2014-12-25 13:18:39

2010-05-25 15:07:37

惠普云计算简化

2010-05-24 18:05:43

惠普云计算IT管理

2009-07-08 15:35:18

Case类Scala

2009-07-22 07:57:00

ScalaCurry化函数

2009-09-28 10:26:12

Scala代码实例Kestrel

2009-07-22 09:22:20

Scala工厂对象
点赞
收藏

51CTO技术栈公众号