Scala模式与异步或未来匹配

时间:2015-04-16 07:24:39

标签: scala concurrency

示例代码段:

def evalExpr(e: Expr): Int = e match {
  case Num(n) => n
  case Sum(l, r) => evalExpr(l) + evalExpr(r)
  case Prod(l, r) => evalExpr(l) * evalExpr(r)
}

evalExpr异步运行的情况下实现模式匹配的最佳方法是什么?

2 个答案:

答案 0 :(得分:7)

你可以用Scala的期货包装它们:

  import scala.concurrent.Future
  import scala.concurrent.ExecutionContext.Implicits.global
  trait Expr
  case class Num(n:Int) extends Expr
  case class Sum(n:Expr,m:Expr) extends Expr
  case class Prod(n:Expr,m:Expr) extends Expr

  def evalExpr(e: Expr): Future[Int] = e match {
    case Num(n) => Future(n)
    case Sum(l, r) =>
    val exp1 = evalExpr(l)
    val exp2 = evalExpr(r)
      for{
        i<-exp1
        j<-exp2
      } yield i + j

    case Prod(l, r) =>  
     val exp1 = evalExpr(l)
     val exp2 = evalExpr(r)
     for{
        i<-exp1
        j<-exp2
      } yield i + j
  }

evalExpr(Prod(Sum(Num(1),Prod(Num(3),Num(2))),Num(2))).map(println)


scala> evalExpr(Prod(Sum(Num(1),Prod(Num(3),Num(2))),Num(2))).map(println)
8 // As you can see output of the calculation is asynchronously printed. 
res0: scala.concurrent.Future[Unit] = scala.concurrent.impl.Promise$DefaultPromise@65039982

答案 1 :(得分:1)

如果evalExpr(Expr)将返回Future[Int],您可以像这样写Prod(l, r)

case Prod(l, r) => {
  val eval1 = evalExpr(l)
  val eval2 = evalExpr(r)
  for {
    left <- eval1
    right <- eval2
  } yield left*right
}

这将两个期货 - 左派和右派 - 结合在一起,并带来新的未来。

使用期货case Num(n)也应该是=> Future(n)