使用if-else中的重复代码减少代码重复

时间:2015-09-02 07:49:21

标签: scala dry

我想知道下面的简短片段是否显示重复可以更干。我似乎经常打这种结构。

假设我想要在运行时选择同步或异步的某些计算。

for(i <- 1 to reps) {
  Thread.sleep(expDistribution.sample().toInt)
  if (async) {
    Future {
      sqlContext.sql(query).collect()
    }
  } else {
    sqlContext.sql(query).collect()
  }
}

重复调用sqlContext会感到笨拙。这个琐碎的重复构造是否有成语?

2 个答案:

答案 0 :(得分:6)

您可以将计算“存储”在本地def中,然后同步或异步评估

def go = sqlContext.sql(query).collect()

if(async) Future(go) else Future.successful(go)

答案 1 :(得分:1)

您可以使用MoreExecutors.directExecutor()中实现的guava library在当前帖子中演示Future

(如果你不想使用番石榴库,请参阅this question

使用此方法,您可以根据async标志切换执行上下文。

以下是示例代码。

您可以看到将async标记设置为false会使每个Future按顺序执行。

import com.google.common.util.concurrent.MoreExecutors
import scala.concurrent.{Future,ExecutionContext}
import java.lang.Thread
object Main {
  def main(args:Array[String]){
      val async = false // change this to switch sync/async
      implicit val ec = if(async){
        ExecutionContext.Implicits.global // use thread pool
      }else{
        ExecutionContext.fromExecutor(MoreExecutors.directExecutor) // directy execute in current thread
      }

      println(Thread.currentThread.getId)

      Future{
        Thread.sleep(1000)
        println(Thread.currentThread.getId)
      }
      Future{
        Thread.sleep(2000)
        println(Thread.currentThread.getId)
      }
      Thread.sleep(4000) // if you are doing asynchronously, you need this.
  }
}