1

我有以下代码

class LazyLogRecord(
  level: javalog.Level,
  messageGenerator: => AnyRef
     ) extends LogRecord(level, "") {

  // for each logged line, generate this string only once, regardless of how many handlers  there are:
  override lazy val getMessage : String = messageGenerator().toString
}

此代码无法编译,因为我尝试调用 messageGenerator。我可以修改代码

messageGenerator: => AnyRef
to
messageGenerator: () => AnyRef

但是然后我的上游代码 log.debug("hi there"+variable+"asfdsaf") 不会编译,除非我将该代码更改为 log.debug( () => {"hi there"+variable+"asdfas"} )

如果我只是坚持使用 messageGenerator.toString,getMessage 将返回“function0”,而不是在该结果上调用 toString 的调用函数结果。

我该如何解决这个问题才能两全其美?

编辑:很奇怪,我只是将代码修改为此

override lazy val getMessage : String = {
   val funkyThing : () => AnyRef = messageGenerator
   funkyThing().toString
}

当它应该说类型“=> AnyRef”时,它说mesasgeGenerator是类型“AnyRef”。然后它抱怨它不能将“AnyRef”转换为“()=> AnyRef”

那里发生了什么?那也不对。

编辑2:我开始认为这是一个客户问题。我的客户端代码可能是错误的。我的客户端代码是这样的,其中我传递了一个传递给 LazyLogRecord 的函数……我对函数的定义是错误的吗?我认为它就像我将它传递给 => AnyRef 并且它不是完全相同的类型,但我需要测试惰性评估并且它失败了。

  val logger = Logger.get("lazyTest2")
  logger.setLevel(Level.DEBUG)
  var executed = false
  val function = () => {
    executed = true
    "asdf"+executed+" hi there"
  }


  logger.debugLazy(function)
  assert(!executed)

谢谢,院长

4

1 回答 1

2

根据您的最新更新,将您的呼叫更改为:

val logger = Logger.get("lazyTest2")
logger.setLevel(Level.DEBUG)
var executed = false


logger.debugLazy({
  executed = true
  "asdf"+executed+" hi there"
})

应该解决你的问题。您之前的代码被解释为:

logger.debugLazy({function})

这是一个返回你的 function0 的函数,因为它的结果不是你想要的。您也可以尝试定义function为 def 而不是像这样的 val:

def function() = {
  executed = true
  "asdf"+executed+" hi there"
} 
logger.debugLazy(function)

这也应该有效。

于 2014-08-12T19:05:47.430 回答