在Scala中相同Object的2个方法之间传递值

问题描述:

我希望将var/val的值从一种方法传递给另一种方法。
例如,我有在Scala中相同Object的2个方法之间传递值

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类,它对我也不起作用。

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

对此的常见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 
} 
+0

谢谢RussS!在我的情况下,我被绑定到设计上,并且我无法做出任何更改..但是我爱你的答案。 :)它整洁有效,以及 – underwood

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 
    } 
} 
+0

使用队列是一个很好的!谢谢@ jwvh – underwood

根据您的要求,最好这样做。

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> 

,这样你可以有一个单工作(可以肯定的,开始和结束将是你把所有工作一样。)