问题
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