• 编程中的链式调用: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 对象。

  • 相关阅读:
    github设置添加SSH
    pythonanywhere笔记
    Python3x 爬取妹子图
    python3.4 百度API接口
    简易博客开发(8)----django1.9 博客部署到pythonanywhere上
    Python3.4+Django1.9+Bootstrap3
    docker搭建私有仓库之harbor
    docker新手常见问题和知识点
    node之sinopia搭建本地npm仓库
    rancher-HA快速搭建
  • 原文地址:https://www.cnblogs.com/lovesqcc/p/6580875.html
Copyright © 2020-2023  润新知