编程中的链式调用:Scala示例
2017-03-19 16:22
211 查看
编程中的链式调用与Linux Shell 中的管道类似。Linux Shell 中的管道 ,会将管道连接的上一个程序的结果, 传递给管道连接的下一个程序作为参数进行处理,依次串联起N个实用程序形成流水线处理。流水线处理技术显得比较优雅可读。比如使用 Supervisor 管理后台任务时, 要重启所有任务, 可以使用
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。
而以下代码则典型地呈现了列表的链式调用。
链式调用并不一定会提升性能, 主要是代码实现的美观性和可读性。
注意到,这里 object P3xPlus1Number 是类 P3xPlus1Number 的伴生对象,主要用于构造 P3xPlus1Number 对象以及放置相关的静态工具方法。 这也是 Scala 的一个小小的设计理念差异之处: 将实例方法与类方法分离开。定义 apply 方法使得客户端不用 new 关键字就可以构造 P3xPlus1Number 对象。
sudo supervisorctl status | grep "RUNNING" | cut -f 1 -d' ' | grep '\-8' | awk '{print "sudo supervisorctl restart " $0"\nsleep 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 对象。
相关文章推荐
- 第51讲:Scala中链式调用风格的实现代码实战及其在Spark编程中的广泛运用
- 51.Scala中链式调用风格的实现代码实战及其在Spark编程中的广泛运用
- Scala中链式调用风格的实现代码实战及其在Spark编程中的广泛运用之Scala学习笔记-41
- 第51讲:Scala中链式调用风格的实现代码实战及其在Spark编程中的广泛运用学习笔记
- Scala深入浅出进阶经典 第51讲:Scala中链式调用风格的实现代码实战及其在Spark编程中的广泛运用
- JavaSE8基础 链式编程 调用方法返回对象再调方法 简单示例
- Promise编程模式中链式调用时传值的一个小坑
- 驾驶证机动车查询验证WebSerivce调用编程接口说明及示例代码
- Python实现类似jQuery使用中的链式调用的示例
- Scala 深入浅出实战经典 第51讲:Scala中链式调用风格的实现代码实战及其在Spark中应用
- C++调用Lua编程环境搭建及测试代码示例
- Scala中链式调用
- Scala进阶源码实战之七——链式调用、结构类型
- Windows编程模型与API调用示例
- WCF热门问题编程示例(2)多个实例调用一个WCF服务操作,需要等待服务响应吗
- C++调用Lua编程环境搭建及测试代码示例
- 【转载】WCF热门问题编程示例(4):WCF客户端如何异步调用WCF服务?
- WCF热门问题编程示例(2)多个实例调用一个WCF服务操作,需要等待服务响应吗
- C++调用Lua编程环境搭建及测试代码示例
- WCF热门问题编程示例(4):WCF客户端如何异步调用WCF服务?