how to allow passing in a => AnyRef function and call that function

烈酒焚心 提交于 2019-12-11 12:34:49

问题


I have the following code

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
}

This code does not compile because I try to invoke messageGenerator. I can modify the code from

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

but then my upstream code log.debug("hi there"+variable+"asfdsaf") does not compile unless I change that code to log.debug( () => {"hi there"+variable+"asdfas"} )

If I just stick with messageGenerator.toString, the getMessage is returning "function0" instead of the invoked function results with toString called on that result.

How can I fix this to have the best of both worlds?

EDIT: Very odd, I just modified the code to this

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

and it says mesasgeGenerator is type "AnyRef" when it should say type "=> AnyRef". It then complains it can't convery "AnyRef" to "() => AnyRef"

what is going on there? That isn't right either.

EDIT 2: I am beginning to think it is a client problem. My client code may be wrong. My client code was like this where I pass in a function that is passed down to LazyLogRecord....is my definition of function wrong? I think it is as then I pass it to => AnyRef and it's not exactly that same type but I needed to test the lazy evaluation out and it failed.

  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)

thanks, Dean


回答1:


Based on your latest update, changing your call to:

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


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

Should fix your issue. Your previous code is being interpreted as:

logger.debugLazy({function})

which is a function that returns your function0 as it's result which is not what you wanted. You could also try defining function as a def instead of a val like so:

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

and that should work as well.



来源:https://stackoverflow.com/questions/25270193/how-to-allow-passing-in-a-anyref-function-and-call-that-function

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!