• scala-- 高阶函数


    高阶函数

    高阶函数:以其它函数做参数的函数。

    高阶函数的好处之一:可以让你创造抽象控制从而减少代码重复。

    import java.io.File
    
    object Test{
      private def filesHere = new File(".").listFiles //获得当前目录下的所有文件名
      def filesMatching(query:String,matcher:(String,String)=>Boolean):Unit = {//①
        for(file <- filesHere; if matcher(file.getName,query))//②  //遍历目录下所有文件,如果某个文件的文件名符合matcher函数返回真的条件,那么就返回该文件
          yield file
      }
      def filesEnding(query:String) = {//③   查询以query结尾的文件名
        filesMatching(query,_.endsWith(_))//④
      }
      def filesContaining(query:String) = { //查询包含query的文件名
        filesMatching(query,_.contains(_))
      }
      def filesRegex(query:String) = { //  查询符合query 正则的文件名
        filesMatching(quey,_.matches(_))//⑤
      }
    }
    /*
    ①:filesMatching 方法有两个参数,一个String类型,参数名为query,一个为函数类型,参数名为matcher。
    (String,String) => Boolean 中 “=>”  说明这是一个函数类型。该函数类型接受两个字符串参数,并且返回一个布尔值。这是一个类型就像String,Int类型一样,它只是规定一个“要求” ,而它的字面量要去具体实现它的要求。像字符串类型,要求它的字面量是一个任意的字符串。Int类型要求它的字面量是一个任意的数值。这个函数类型要求它的字面量是一个任意的 接受两个字符串参数 并且返回一个布尔值的函数字面量(也叫函数值)
    
    ②:match(file.getName,query)  这条语句,定义了如何使用函数类型,如何传参,也就是说,给出了对具体的 函数字面量的使用方法,以及传参的方式。
    
    ③:定义了一个方法————文件名以某些字符串为结尾的查询方法。它的函数体内部调用“实例化了”的filesMatching方法。具体来说,就是 “._endsWith(_)” 这个短小的方法/函数字面量 即为 上文 matcher 类型的具体实现 。从而获取以 query 为结尾的文件。下面三个类似原理。
    
    ④:_.endsWith(_) 这个函数字面量,用到了 “_” 占位符。当一条语句中出现多个“_”时,它并不表示而且不允许,一个参数(这里的参数只是这个小小的字面量的参数)的重复出现,而是,一个"_"表示一个不同的参数。也就是说前后两个是而且必须“代指”着不同的东西。根据上面matcher中的使用方法定义  if matcher(file.getName,query),我们可以知道第一个"_" 代表file.getName 即文件名,后一个"_"表示 query,所以,_.endsWith(_)的真是意思是
    (file.geName).endsWith(query)。
    
    ⑤:通过观察发现可以  filesEnding filesContaining  filesRegex三个方法,接收了一个query参数作为查询条件,然后都把query传给了各自内部的 filesMatching()函数,然而,filesMatching把query当作了第一个参数,然后就没有然后了,它没有对query参数做任何操作,除了将其又作为参数传给filesMatching的第二个参数,matcher类型的函数字面量,做第二个参数。这个query多次传播并没有意义,而且,filesMatching作为一个被本地函数,它本就能够访问上面三个方法中的各种参数。所以,这就意味着,三个方法,再次将query传递给filesMatching函数是没必要的。所以,matcher的三个具体实现可以进行修改,舍弃query方法。又然而它们是matcher函数类型的字面量,所以需要从源头上进行修改,也就是说,对matcher类型进行修改才行。所以matcher修改为如下类型:
    matcher: String => Boolean 即接受一个字符串参数,返回一个布尔值。
    ..... if matcher(file.getName) .....
    所以下面的三个本地函数也就可以相应的修改为 
    filesMatcher(_.endsWith(query)),filesMatcher(_.contains(query)).当然第一个“_”还是代表文件名。
    
    ⑥:在 ⑤未修改之前,_.endsWith(_)虽然有两个参数,但是他们都是通过matcher(file.getName,query)两个参数进行了绑定。然而filesMatcher(_.endsWith(query))修改后,第一个“_”依旧通过matcher(file.getName) 来后去了filename的帮定。然后query并没有获取传参,没办法绑定。因而成了自由变量,但是通过本地函数所处上下文,它并不是纯粹的自由变量了,它是通过捕获filesEnding(query) 中的参数query来获得绑定的。因此 filesMatcher(_.endsWith(query)) 是个闭包。
    
    */
    
    
  • 相关阅读:
    python调用php函数
    api响应类
    php 利用socket发送GET,POST请求
    php的异常和处理
    predis操作大全
    PHP 实现HASH表
    PHP 实现Session入库/存入redis
    PHP下使用Redis消息队列发布微博
    jquery 仿163网易图片新闻幻灯片展示
    6种非常酷炫的jquery banner焦点图片幻灯片切换
  • 原文地址:https://www.cnblogs.com/jijizhazha/p/7220154.html
Copyright © 2020-2023  润新知