9.2 简化调用方代码
前面这个例子展示了高阶函数如何帮助我们在实现API时减少代码重复的。高阶函数的另一个重要的用处是将高阶函数本身放在API当中来让调用方代码更加精简。Scala集合类型提供的特殊用途的循环方法是很好的例子。[1]它们当中很多都在第3章的表3.1中列出过,不过现在让我们再看一个例子来搞明白为什么这些方法是很有用的。
我们来看exists,这个方法用于判定某个集合是否包含传入的值。当然可以通过如下方式来查找元素:初始化一个var为false,用循环遍历整个集合检查每一项,如果发现要找的内容,就把var设为true。参考下面这段代码,判定传入的List是否包含负数:
如果你在解释器中定义了这个方法,可以这样来调用它:
不过更精简的定义方式是对传入的List调用高阶函数exists,就像这样:
这个版本的containesNeg将交出跟之前一样的结果:
这个exists方法代表了一种控制抽象。这是Scala类库提供的一个特殊用途的循环结构,并不是像while或for那样是语言内建的。在前一节,高阶函数filesMatching帮助我们在对象FileMatcher的实现中减少了代码重复。这里的exists也带来了相似的好处,不过由于exists是Scala集合API中的公共函数,它减少的是API使用方的代码重复。如果没有exists,而又打算编写一个containsOdd方法来检查某个列表是否包含奇数,可能会这样写:
如果对比containsNeg和containsOdd,你会发现所有的内容都是重复的,除了那个用于测试条件的if表达式。如果用exists,可以这样写:
这个版本的代码体再一次跟对应的containsNeg方法一致(使用exists的版本),除了搜索条件不同。这里的重复代码要少得多,因为所有的循环逻辑都被抽象到exists方法里了。
Scala类库当中还有许多其他循环方法。跟exists一样,它们通常能帮助你缩短代码,如果你能找到机会使用它们。