在Scala中传递同一对象的两个方法之间的值

时间:2016-09-06 21:49:41

标签: scala

我希望将var / val的值从一种方法传递给另一种方法 例如,我有

object abc {

  def onStart = {    
    val startTime = new java.sql.Timestamp( new Date())
  }

  def onEnd = {
    //use startTime here 
  }
}

致电:

onStart()  
executeReports(reportName, sqlContexts)  
onEnd()  

此处onStart()onEnd()executeReports()的工作监控功能 executeReports()在5个报告的循环中运行。

我尝试使用像

这样的全局变量
object abc{

  var startTime : java.sql.Timestamp = _

  def onStart = {    
    startTime = new java.sql.Timestamp( new Date())
  }

  def onEnd = {
    //use startTime here 
  }

}

但是这个问题是当循环为下一个报告执行时,startTime不会改变。

我也尝试过使用不适用于我的Singleton Class。

我的要求是每次迭代都有一个startTime,即每个报告。 欢迎任何想法在这里。如果需要,我很乐意提供更多关于我的要求的说明。

3 个答案:

答案 0 :(得分:5)

Scala的常见解决方案是编写一个包装其他函数的函数,并在内部执行设置和关闭。

def timeit[T]( fun: => T ): T = {
  val start = System.currentTimeMillis //Do your start stuff
  val res = fun
  println (s"Time ${System.currentTimeMillis - start}") // Do your end stuff
  res
}

答案 1 :(得分:1)

RussS有更好的解决方案,但如果由于某种原因你已经结合了你所描述的设计,你可能会尝试使用一个可变的val,即一个可变的集合。

我得到这个来编译并通过一些小测试。

object abc {
  private val q = collection.mutable.Queue[java.sql.Timestamp]()

  def onStart = {
    q.enqueue(new java.sql.Timestamp(java.util.Calendar.getInstance().getTime.getTime))
  }

  def onEnd = {
    val startTime = q.dequeue
  }
}

答案 2 :(得分:0)

根据您的要求,这样做可能会更好。

case class Job(report: List<Report>) {
 def execute // does the looping on Report by calling start and call end to generate monitoring data

 private def start // iterate over each Report and calls it's execute method

 private def end // iterate over each Report and uses startTime and executionTime to generate monitoring data. 
}

abstract class Report {
 var startTime: DateTime //Time started for the report
 def doReport // unimplemented method that does the report generation. 
 def execute // first set stateTime to Now then call doReport, lastly calculate executionTime
}

报告的子类型应实现执行实际报告的doReport。

您还可以将Job.execute方法更改为

report: List<Report>

这样你就可以拥有一个单独的工作(当然,你所有的工作的开始和结束都是一样的。)