Scala Comprehensions

本文介绍了Scala中for与if组合使用的方法,包括如何通过yield关键字简化代码,以及如何在推导内部定义值而不存储中间结果。此外还展示了推导可以嵌套使用的特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原创转载请注明出处:http://agilestyle.iteye.com/blog/2333647

 

for和if的组合称为for推导,简称为推导。先看一个简单的例子:

package org.fool.scala.comprehension

object ComprehensionTest extends App {
  def evenGT5(v: Vector[Int]): Vector[Int] = {
    // 'var' so we can reassign 'result'
    var result = Vector[Int]()

    for {
      n <- v
      if n > 5
      if n % 2 == 0
    } result = result :+ n

    result
  }

  val v = Vector(1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 13, 15, 17, 20)
  println(evenGT5(v))
}
Note:

result为var而不是val

Vector有一个操作符“:+”,它会接受一个Vector(但是不会修改它),并将操作符右边的元素与其组合起来,以此创建一个新的Vector。

Console Output


 

有一种将result用作val(而不是var)的方式:by building result "in place" rather than creating it piece-by-piece。为了实现这个目的,可是使用Scala的yield关键字。当你声明yield n时,它会将值n "yield up"出来,使其成为result的一部分。

package org.fool.scala.comprehension

object Yielding extends App {
  def yielding(v: Vector[Int]): Vector[Int] = {
    val result = for {
      n <- v
      if n < 10
      if n % 2 != 0
    } yield n
    result
  }

  val v = Vector(1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 13, 15, 17, 20)
  println(yielding(v))
}
Console Output


 

接下来在推导内部定义值,并且不存储和返回中间结果result

package org.fool.scala.comprehension

object Yielding2 extends App {
  def yielding2(v: Vector[Int]): Vector[Int] = {
    for {
      n <- v
      if n < 10
      isOdd = (n % 2 != 0)
      if (isOdd)
    } yield n
  }

  val v = Vector(1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 13, 15, 17, 20)
  println(yielding2(v))
}
Console Output


 

与其他任何表达式一样,yield表达式也可以组合

package org.fool.scala.comprehension

object Yielding3 extends App {
  def yielding3(v: Vector[Int]): Vector[Int] = {
    for {
      n <- v
      if n < 10
      isOdd = (n % 2 != 0)
      if (isOdd)
    } yield {
      // only inside the comprehension can you get away without declaring val or var for new identifiers.
      val u = n * 10
      u + 2
    }
  }

  val v = Vector(1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 13, 15, 17, 20)
  println(yielding3(v))
}
Note:

只有在推导内部才能不为新标识符声明val或var

Console Output


 

可以将一个推导只与一个yield表达式相关联,并且不能将yield表达式置于推导体之前。但是推导可以嵌套:

package org.fool.scala.comprehension

object Yielding4 extends App {
  def yielding4(v: Vector[Int]) = {
    for {
      n <- v
      if n < 10
      isOdd = (n % 2 != 0)
      if (isOdd)
    } yield {
      for (u <- Range(0, n))
        yield u
    }
  }

  val v = Vector(1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 13, 15, 17, 20)
  println(yielding4(v))
}
Console Output


 

参考资料:

Scala编程思想 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值