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