单身人士仅在Scala中可用一次

时间:2015-11-09 07:28:31

标签: scala macros singleton

我们经常需要可以重复使用的对象,并且需要一些时间来生成:

def foo() = {
  // long lines of code...
  val pattern = Pattern.comile("pattern") // suppose this takes long time
  // use pattern
}

然后它可以移动到外部范围

private[this] lazy val pattern = Pattern.comile("pattern") // suppose this takes long time

def foo() = {
  // long lines of code...
  // pattern need to be available only here!
  // use pattern
}

但是这会使源变得复杂,因为它会泄漏变量pattern的范围,而它仅在foo的特定位置使用。我很好奇这可以用宏功能简化:

def foo() = {
  // long lines of code...
  val pattern = singleton { Pattern.comile("pattern") }
  // use pattern
}

如果可能,我们可以扩展它以获得更有趣的案例; ThreadLocal单身人士:

def foo() = {
  // long lines of code...
  val obj = threadLocal { new NotThreadSafeObject() }
  // use obj
}

将扩展为:

private[this] lazy val foo_obj_gen_by_macro = {
  val tl = new ThreadLocal[NotThreadSafeObject]()
  tl.set(new NotThreadSafeObject())
  tl
}
def foo() = {
  // long lines of code...
  val obj = foo_obj_gen_by_macro.get
  // use obj
}

如果是C ++,可以通过在函数范围内使用static变量来轻松实现:

void foo() {
    // long lines of code...
    static Pattern pattern = Pattern.Compile("pattern");
    // use pattern
}

1 个答案:

答案 0 :(得分:1)

为什么不只是范围呢?

  lazy val foo: () => String = {
    val pattern = Pattern.compile("pattern")

    def result(): String = ???

    result _
  }

thoredge mentioned甚至更简单

lazy val foo: () => String = {
    val pattern = Pattern.compile("pattern")

    () => ???
  }