我是scala的新手,想知道如何访问在for循环中定义的val,并希望将该val写入for循环外的文件。
def time[A](logFile: String, description: String)(job: => A): Unit = {
var totalDuration: Long = 0
for (i <- 1 to 3) {
val currentTime = System.currentTimeMillis
val result = job
val finalTime = System.currentTimeMillis
val duration = finalTime - currentTime
totalDuration = if (totalDuration == 0) duration else totalDuration.min(duration)
}
val pw = new PrintWriter(new FileOutputStream(new File(logFile),true))
pw.write(description + " " + result + " " + totalDuration +" ms"+"\n")
pw.flush()
pw.close
}
在上面的代码中,我正在计算我的结果,其中包含从其他函数读取的字节长度,并希望计算读取总字节所需的时间。我想迭代3次并取三者中的最小值。 val结果包含字节长度,也需要在文件中写入。我得到一个错误,因为我正在访问for循环范围之外的结果val。有人可以帮我解决这个错误。如何在for循环中访问val结果以将其写入文件?
提前致谢!!
答案 0 :(得分:0)
您可以使用收益。在完成循环后,Yield将从for循环返回数据并相应地使用该数据。因为我没有你的代码。看这个例子
$(OBJS)
j的输出将是
val j = for (i <- 1 to 10) yield i
println(j)
答案 1 :(得分:0)
要替换for循环以计算按顺序执行的某些作业的总持续时间,您可以使用foldLeft
答案 2 :(得分:0)
利用收益率或您可以使用任何折叠方法。或者如果你对递归很好,你可以使用tailrec方法返回Desired。产量是最简单的方法。
val answer = for(i<- 1 to 10) yield i
println(answer) // Vector(1,2,3,4,5,6,7,8,9,10)
答案 3 :(得分:0)
当您的问题得到解答时,for循环不是典型的形式,看起来更像是这样:
def time[A] (logFile: String, description: String) (job: => A): Unit = {
val (result, totalDuration): (A, Long) = (for { i <- 1 to 3
currentTime = System.currentTimeMillis
result = job
finalTime = System.currentTimeMillis
duration = finalTime - currentTime
} yield (result, duration)).minBy {case (r, d) => d}
val pw = new PrintWriter (new FileOutputStream (new File (logFile), true))
pw.write (description + " " + result + " " + totalDuration +" ms"+"\n")
pw.flush()
pw.close
}
如果我正确理解您的代码。我不知道副作用是否会导致每个作业调用的结果不同。
我错过了for-loop发明/定义的内部讨论,为什么这里应该省略关键字val
,但它很安静。
更重要的是,您通常在for (...(here part)...) { not here}
中拥有所有临时任务。第一部分中圆形或花括号的后果对我来说并不完全清楚,但如果使用圆形括号,则可以用分号终止大多数语句。
scala> for (i <- 1 to 3;
| j <- 4 to 5;
| k = j-i;
| l = k/2) yield l * l;
res2: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 4, 1, 1, 0, 1)
注意i,j,k,l都没有声明为val或var。
scala> for {i <- 1 to 3
| j <- 4 to 5
| k = j-i
| l = k/2} yield l * l;
res3: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 4, 1, 1, 0, 1)
你会在这里找到多个问题,它们解释了for循环是如何并且可以转换为flatMap / map-combination,最终使用filter:
scala> for {i <- 1 to 3
| j <- 4 to 5
| k = j-i
| if (k > 1)
| l = k/2 } yield l * l;
res5: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 4, 1, 1, 1)
而不是只产生一个值,你可以产生一个元组,并通过
分配 val (a:X, b:Y) = (for ..... yield (aa, bb))
yield (result, duration)).minBy {case (r, d) => d}
取一个元组(结果,持续时间)并按持续时间选择最小值,但产生两个值。