zoukankan      html  css  js  c++  java
  • 编程中的链式调用:Scala示例

    编程中的链式调用与Linux Shell 中的管道类似。Linux Shell 中的管道 ,会将管道连接的上一个程序的结果, 传递给管道连接的下一个程序作为参数进行处理,依次串联起N个实用程序形成流水线处理。流水线处理技术显得比较优雅可读。比如使用 Supervisor 管理后台任务时, 要重启所有任务, 可以使用

    sudo supervisorctl status | grep "RUNNING" | cut -f 1 -d' ' | grep '-8' | awk '{print "sudo supervisorctl restart " $0"
    sleep 2 " }' > /tmp/restart.sh && sh /tmp/restart.sh
    

    sudo supervisorctl status 打印所有supervisor管理的后台任务及状态, 并传给 grep ;grep 筛选出文本中含有 RUNNING 的内容传给 cut ;cut 程序根据空格对内容切分字段,只保留第一个字段的值,然后传给 grep; grep 同样筛选出内容只含有 -8 的任务内容, 传给 awk ; 最后 awk 根据传入的内容组装新的内容行, 重定向写入文件 /tmp/restart.sh 中; 如果以上流水线处理成功, 那么就会执行 sh /tmp/restart.sh。

    编程中的链式调用类似: 上一个对象 A 的方法调用 a 的结果对象 B,接着调用 B 的方法 b 得到 C, 接着调用 C 的方法 c 得到 D, 像成语接龙一样;对于列表元素的批量处理尤其适合。 而对于对象来说,为了制造链式调用,则需要返回相同父类型的对象, 或者规划好一系列可以连续调用的对象。

    以下是一个Scala程序示例, 通过 3x+1 谜题演示链式调用。 P3xPlus1Number 含有个方法 do3xplus1,做一次迭代后返回自身,从而可以连续调用 do3xplus1。

    package scalastudy.basic
    
    /**
     * Created by shuqin on 17/3/19.
     *
     * 3x+1 谜题, 演示链式调用
     */
    object Puzzle3xPlus1 extends App {
    
        println(P3xPlus1Number(78).do3xplus1().do3xplus1().do3xplus1())
        println(P3xPlus1Number(78).solve())
        1 to 1000 map { P3xPlus1Number(_).solve() } map { t => (t._1, t._2) } foreach { println }
    }
    
    class P3xPlus1Number(init:Int) {
    
        var innerNumber = init
    
        def do3xplus1(): P3xPlus1Number = {
            innerNumber = if (innerNumber%2==1) { innerNumber*3+1 } else { innerNumber/2 }
            this
        }
    
        def solve(): (Int, Int, List[Int]) = {
            var sol = (init, 0, List[Int]())
            while (innerNumber != 1) {
                sol = (init, sol._2 + 1, innerNumber::sol._3)
                do3xplus1()
            }
            (init, sol._2 + 1, (innerNumber::sol._3).reverse)
        }
    
        override def toString():String = {
            "P3xPlus1Number["+innerNumber+"]"
        }
    }
    
    object P3xPlus1Number {
        def apply(init:Int): P3xPlus1Number = {
            new P3xPlus1Number(init)
        }
    }
    
    

    而以下代码则典型地呈现了列表的链式调用。

    1 to 1000 map { new P3xPlus1Number(_).solve() } map { t => (t._1, t._2) } foreach { println }
    

    链式调用并不一定会提升性能, 主要是代码实现的美观性和可读性。

    注意到,这里 object P3xPlus1Number 是类 P3xPlus1Number 的伴生对象,主要用于构造 P3xPlus1Number 对象以及放置相关的静态工具方法。 这也是 Scala 的一个小小的设计理念差异之处: 将实例方法与类方法分离开。定义 apply 方法使得客户端不用 new 关键字就可以构造 P3xPlus1Number 对象。

  • 相关阅读:
    IOS苹果应用IPA一键签名工具(苹果重签名,企业签名,Windows平台,时间控制)
    BZ全景编辑器
    HTML/网站一键打包APK工具(html网页打包安卓APP应用)
    HTML网页/KRPano项目一键打包EXE工具(HTML网页打包成单个windows可执行文件exe)
    KRPano资源分析工具使用说明(KRPano XML/JS解密 切片图批量下载 球面图还原 加密混淆JS还原美化)
    IOS苹果应用IPA重签名软件手机版(苹果重签名,企业签名,安卓苹果平台,时间控制)
    使用HTML一键打包IPA工具打包KRPANO全景项目
    使用HTML一键打包APK工具打包KRPANO全景项目
    使用HTML一键打包EXE工具打包KRPANO全景项目
    从现实产品生产理解创建型设计模式
  • 原文地址:https://www.cnblogs.com/lovesqcc/p/6580875.html
Copyright © 2011-2022 走看看