将代码块传递给方法而不执行

时间:2014-12-26 02:30:08

标签: scala

我有以下代码:

import java.io._
import com.twitter.chill.{Input, Output, ScalaKryoInstantiator}

import scala.reflect.ClassTag

object serializer {

  val instantiator = new ScalaKryoInstantiator
  instantiator.setRegistrationRequired(false)
  val kryo = instantiator.newKryo()

  def load[T](file:_=>_,name:String,cls:Class[T]):T = {
    if (java.nio.file.Files.notExists(new File(name).toPath())) {
      val temp = file
      val baos = new FileOutputStream(name)
      val output = new Output(baos, 4096)
      kryo.writeObject(output, temp)
      temp.asInstanceOf[T]
    }
    else {
      println("loading from " + name)
      val baos = new FileInputStream(name)
      val input = new Input(baos)
      kryo.readObject(input,cls)
    }
  }
}

我想以这种方式使用它:

val mylist = serializer.load((1 to 100000).toList,"allAdj.bin",classOf[List[Int]])

我不想每次都运行(1 to 100000).toList因此我想将它传递给序列化程序,然后决定第一次计算它并将其序列化以备将来使用或从文件中加载它。 / p>

问题是代码块在我的代码中首先运行,如何在不执行代码块的情况下传递代码块?

P.S。是否有任何scala工具可以为我做一些确切的事情?

1 个答案:

答案 0 :(得分:3)

要在传递参数之前不进行评估,请使用pass-by-name,如下所示:

def method(param: =>ParamType)

您通过的任何内容都不会在您通过时进行评估,但每次使用param时都会对其进行评估,这可能不是您想要的。要仅在您第一次使用时对其进行评估,请执行以下操作:

def method(param: =>ParamType) = {
  lazy val p: ParamType = param

然后在身体上仅使用p。第一次使用p时,将评估param并存储该值。 p的所有其他用途都将使用存储的值。

请注意,每次调用method时都会发生这种情况。也就是说,如果您拨打method两次,它将不会使用{存储的'p值 - 它会在首次使用时再次评估它。如果你想“预先计算”一些东西,那么也许你最好选择一个班级?