Chapter 23《For Expressions Revis

作者: liqing151 | 来源:发表于2018-07-09 19:01 被阅读5次

    for表达式

    • for表达式一般是for ( seq ) yield exprseq是一个序列,包含有生成器、定义和过滤器,它们用分号隔开。
      for {
      p <- persons  // a generator
      n = p.name    // a definition
      if (n startsWith "To")  // a filter
      } yield n
      
      生成器的格式如下,pat <- exprexpr通常返回一个列表。如果匹配成功,模式中的变量就会成功绑定,如果匹配不成功,当前元素仅仅就是被丢掉了,并不会有MatchError抛出。
      定义的格式如下:pat = expr
      过滤器的格式:if expr,过滤器会将迭代中所有让exprfalse的元素丢弃。for中可以含有多个生成器,如果一个for表达式中有多个生成器,则出现在后面的生成器是嵌套在前面的生成器中,后面的生成器出现的更频繁。
      for表示法本质上跟数据库查询语言的通用操作是等效的。

    用for推导式进行翻译

    • 每个for表达式都可以使用map,flatMapwithFilter来表示。
      for (x <- expr_1) yield expr_2                  expr_1.map(x => expr_2)
      for (x <- expr_1 if expr_2) yield expr_3        expr_1 withFilter (x => expr2) map (x => expr3)
      for (x <- expr_1; y <- expr_2) yield expr_3     expr_1.flatMap(x => (y.map(y => expr3))
      
      在有多个生成器模式的for语句中,yield的表达式expr_3是用于最后一个生成器的map函数。剩下的生成器都是flatMap
      for (x <- expr_1; y = expr_2; seq) yield expr_3          
      for ((x, y) <- for (x <- expr_1) yield (x,  expr_2); seq) yield expr_3
      
      for中的定义y = expr_2会在每一次迭代x的时候进行计算,如果是和x无关的变量,计算时很耗费,最好把和x无关的操作放在for表达式的外面。如果是没有yield表达式,会直接翻译成foreach
      for (x <- expr_1) body     expr_1 foreach (x => body)
      
      每个map,faltMapwithFilter的应用都可以使用for表达式进行表达。
    • 由于for表达式的翻译仅仅依赖map、faltMap、withFilterforeach,则定义了这些方法的结构也可以生成各种各样的for表达式。
    • 如果withFilter每次都产出一个序列的话,对于序列很大的情况下消耗时间很大,一般的做法返回一个"记住"元素需要被过滤的包装对象,然后再继续处理。

    相关文章

      网友评论

        本文标题:Chapter 23《For Expressions Revis

        本文链接:https://www.haomeiwen.com/subject/wzjtpftx.html