有没有更好的方法在Scala中执行以下if / else处理?

时间:2011-10-04 09:41:12

标签: scala

我有一个事件驱动系统,响应如下交易

def onTrade {

    if (price > threshold) {
        processReject()
        return
    } 

    if (volume > threshold) {
        processReject()
        return
    } 
    .
    .
    .
}

我认为我可以通过定义内部方法来改进语法

def onTrade {

    def filterRemove = (filter: Boolean) => {
        if (filter) {
            processReject()
        }
        filter
    }

    val filters = List(
        filterRemove(price > threshold),
        filterRemove(volume > threshold),...
    )

    if (filters.filter(x => x == true).size > 0) return

}

语法更清晰,特别是随着过滤器数量的增加。我遇到的一个问题是代码通过遍历每个单独的测试而不是在第一次失败时返回来浪费不必要的时钟周期。这有什么办法吗?例如,一旦filterRemove返回false,就退出onTrade。如果有一种更有表现力的方式来做到这一点,我也很想知道这一点。

5 个答案:

答案 0 :(得分:7)

例如,您可以维护拒绝条件列表。然后,您可以使用exists按顺序调用它们。一旦条件为false,迭代就会结束。

这是一个小例子:

val conditions: List[() => Boolean] =
  List(
    () => price > threshold1,
    () => volume > threshold2
  )

def checkAndReject() = {
  val filter = conditions.exists( _() )
  if( filter ) processReject()
  filter
}

答案 1 :(得分:6)

如果你只是想在某些地方写条件,那么不仅仅是使用或者?这是正确的半严格

if (
  price > threshold1
  || volume > threshold2
  || ...
) {
   processReject()
   return
}
... proceed

答案 2 :(得分:4)

问题是你有一个布尔列表 - 它们已经全部处理过了。你需要推迟。例如:

def onTrade {

    // now filterRemove returns Function0[Boolean]
    // also, filter is passed by-name, so it isn't 
    // processed until you call the Function0
    def filterRemove(filter: => Boolean) = () => {
        if (filter) {
            processReject()
            true
        } else false
    }

    // This won't process anything, just accumulate Function0's
    val filters = List(
        filterRemove(price > threshold),
        filterRemove(volume > threshold),...
    )

    // And we use "exists", which returns on the first true value
    if (filters.exists(x => x)) return

}

答案 3 :(得分:3)

这不是一种非常实用或习惯的风格,但可能会引起人们的兴趣:

def onTrade {
    val reject = () => {
        processReject()
        return
    }

    // ...

    if (price > threshold) reject()

    // ...

    if (volume > threshold) reject()

    // ...

}

答案 4 :(得分:0)

如果没有太多要检查的阈值,我会这样做:

def process(price:Int, volume:Int) = (price, volume) match {
   case (x:Int, y:Int) if x > threshold1 || y > threshold2 => println ("reject")
   case _ =>
}

测试如下:

def threshold1 = 10
def threshold2:Int = throw new Exception // redefine to throw exception
def process(price:Int, volume:Int) = (price, volume) match {
   case (x:Int, y:Int) if x > threshold1 || y > threshold2 => println ("reject")
   case _ =>
}

process(12, 22)
process(5, 22)