I have some code block like this:
object EntryPoint extends App {
val arr = ArrayBuffer(1, 2, 3)
doFirst(arr)
def doFirst(a: ArrayBuffer[Int]) = {
doSecond(s"$a")
}
def doSecond(
x: => String = ""
) = {
x match {
case s: String => println(s"This is string: $s")
case _ => println(x.getClass.getName)
}
}
}
Output: This is string: ArrayBuffer(1, 2, 3)
Why x
evaluated like a string if in debugger i see lambda with 3 arguments?
Is it because every call x
is x.apply()
?
CodePudding user response:
A by-name parameter like x: => String
is conceptually the same as a function with signature () => String
The following are equivalent and as you noticed already both parameters end up with the same runtime representation when debugging.
def doWithByNameParam(x: => String): String =
x
def doWithFunction(x: () => String): String =
x.apply()
doWithByNameParam("string")
doWithFunction(() => "string")
You just avoid some boilerplate with doWithByNameParam
Later Edit:
Here's what javap
will give just so you understand what happens under the hood
public static java.lang.String doWithByNameParam(scala.Function0<java.lang.String>);
public static java.lang.String doWithFunction(scala.Function0<java.lang.String>);