注册 登录  
 加关注

网易博客网站关停、迁移的公告:

将从2018年11月30日00:00起正式停止网易博客运营
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

为着理想勇敢前进

 
 
 

日志

 
 

基于Stateless Future的Scala异步编程(五)发生器  

2014-08-04 10:36:57|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
本文首发在岂凡技术小站

Stateless Future支持发生器1。发生器功能类似Scala的for/yield推导式,但发生器比for/yield推导式更灵活。你可以用Stateless Future生成很复杂的惰性求值容器。

用法

首先,想好你的容器中的元素类型,创建一个Generator

import com.qifun.statelessFuture.util.Generator
val gen = Generator[Int] // 创建用来生成Seq[Int]的发生器

然后创建gen.Future

val genFuture = gen.Future {
  for (i <- gen.futureSeq(0 until 3)) {
    gen(i * i).await // 生成容器中的一项,值是i*i
  }
}

gen.Future是一种特殊的Future,专门用于发生器。gen.Futurecom.qifun.statelessFuture.Future的类型有微妙的区别,相互之间不能隐式转换。gen.futureSeq则类似上一节中介绍的futureSeq,可以配合gen.Future使用。

最后把genFuture转换成gen.OutputSeq

val genSeq: gen.OutputSeq = genFuture

gen.OutputSeq派生于SeqgenSeq是个惰性求值的容器,内容是Seq(0, 1, 4, 9)

等价的for/yield推导式

这种惰性求值容器也可以用普通的for/yield推导式生成:

val forYieldSeq: Seq[Int] =
  for (i <- (0 until 10).view) yield { // view后缀使得for语句返回支持惰性求值的SeqView,而不是普通的Seq
    i * i
  }

forYieldSeq也是个惰性求值的容器,内容也是Seq(0, 1, 4, 9)

进阶用法

虽然上例中的for/yield也能涵盖发生器最简单的用法,但是除此之外,发生器中还可以容纳任意控制语句,这种进阶用法就没办法靠for/yield实现了。

import com.qifun.statelessFuture.util.Generator
val gen = Generator[Int]
val genSeq2: gen.OutputSeq = gen.Future {
  gen(-1).await
  for (i <- gen.futureSeq(0 until 3)) {
    gen(i * i).await
    if (i == 2) {
      gen(i).await
      gen(i).await
      gen(i).await
    }
  }
  gen(-2, -3, -2).await // 在一行代码中生成多个元素
}

genSeq2的值是Seq(-1, 0, 1, 4, 2, 2, 2, 9, -2, -3, -2),这样灵活的控制流程,比for/yield功能强。

(待续)


  1. 发生器
    即Generator,是用来控制循环迭代行为的一种特殊子例程。例如C#的yield功能就是发生器。参见维基百科

    ?

  评论这张
 
阅读(656)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018