在Scala模式匹配中使用昂贵语句中的对象

时间:2014-01-29 14:16:42

标签: scala

我有一个昂贵的案例陈述,需要点击数据库来确定完全匹配。如果匹配,则必须使用上述调用的结果执行进一步操作:

def intent = {
    case request @ GET(Path(Seg(database :: Nil))) if recordsFrom(database) != Nil =>
        renderOutput(recordsFrom(database))
    case ...
}

我只想致电recordsFrom(database)一次。在上面的例子中,它被调用两次。看起来我应该能够在声明中应用一些别名吗?

2 个答案:

答案 0 :(得分:3)

劳伦斯,从我看到你使用Unfiltered来处理RESTful请求,但你也将数据库查找与响应过滤相结合。我建议你不要这样做。相反,我会安排如下事项:

val dbReqCommand = new DBRequestCommand(myDbConPool)

def intent ={
  case req @ GET(Path(Seq(database :: Nil))) => dbReqCommand(req, database)
}

其中你已经将db请求封装在一个对象中,你可以替换它来进行测试(想想没有DB后端的集成测试。)在请求处理程序中,你可以放入响应:

Option(recordsFrom(database)) match{
  case Some(value) => OK ~> renderOpupt(value)
  case None => //an error response or Pass
}

这样你可能会有以下几点:

trait DBReqPlan{
  def dbReqCommand: RequestCommand[String]

  def intent ={
   case req @ GET(Path(Seq(database :: Nil))) => dbReqCommand(req, database)
  }
}

更易于测试和使用。

答案 1 :(得分:2)

出了什么问题:

def intent = {
  case request @ GET(Path(Seg(database :: Nil))) =>
    val records = recordsFrom(database) 
    if(!records.isEmpty){ 
      renderOutput(records)
    } else {
      ...
    }
  case ...

如果您想避免使用太多嵌套块,可以将第一个案例的正文移动到另一个函数。