![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=1739283730-bsXQoIG9USB9Pc33THMPGFJADAYNBu25-0-8dd7da27dfcd54868bc7b259f45b8569)
如果你在解释器中定义了这个方法,可以这样来调用它:
![](https://epubservercos.yuewen.com/E8DF3B/20205397808551606/epubprivate/OEBPS/Images/40272-00-202-2.jpg?sign=1739283730-DDseSSs72KCQYrKavO1qIFrStQE4g5Fs-0-dd9a0df55c58d33cc4b99829ea75bf4a)
不过更精简的定义方式是对传入的List调用高阶函数exists,就像这样:
![](https://epubservercos.yuewen.com/E8DF3B/20205397808551606/epubprivate/OEBPS/Images/40272-00-202-3.jpg?sign=1739283730-rPiZtVq4xsOYGF09dlFebFacCzt3ycyI-0-bb0cf4445a219d99ff964cc1ed552279)
这个版本的containesNeg将交出跟之前一样的结果:
![](https://epubservercos.yuewen.com/E8DF3B/20205397808551606/epubprivate/OEBPS/Images/40272-00-203-1.jpg?sign=1739283730-TleKnFP4MkOcMd9LrsUpuqU5TRaLmFOy-0-9dbb0a45e0f8c09e96b81c0dde420998)
这个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=1739283730-YATlmOslO3X0r3sDjxPgs0VR0sw95tvA-0-09acce6ecf7d70f788bcc8ac6d2a780b)
如果对比containsNeg和containsOdd,你会发现所有的内容都是重复的,除了那个用于测试条件的if表达式。如果用exists,可以这样写:
![](https://epubservercos.yuewen.com/E8DF3B/20205397808551606/epubprivate/OEBPS/Images/40272-00-203-3.jpg?sign=1739283730-Lz1lhdgZu4EbPm1gPb4xjPMJOghCtiln-0-ab32cd6d57c6efa5c7dbcc4eef8d69c4)
这个版本的代码体再一次跟对应的containsNeg方法一致(使用exists的版本),除了搜索条件不同。这里的重复代码要少得多,因为所有的循环逻辑都被抽象到exists方法里了。
Scala类库当中还有许多其他循环方法。跟exists一样,它们通常能帮助你缩短代码,如果你能找到机会使用它们。