1. Description
Typically, parameters to functions are by-value parameters; that is, the value of the parameter is determined before it is passed to the function. But what if we need to write a function that accepts a parameter as an expression that we don’t want evaluated until it’s called within our function? For this circumstance, Scala offers call-by-name parameters.
A call-by-name mechanism passes a code block to the call and each time the call accesses the parameter, the code block is executed and the value is calculated.
code example
package com.brown
/**
* Created by BrownWong on 2016/9/29.
*/
object Hello {
def main(args: Array[String]): Unit = {
callByValue(func()) // func()先调用,其返回值作为实参传递给callByValue()函数,然后callByValue()函数调用
println("---------------------")
callByName(func()) // callByName()函数先调用,若函数体内部需要引用参数,才发生求值(func()被调用)
}
def func() = {
println("Calling func()")
1
}
def callByValue(x: Int) = {
println("X1 = " + x)
println("X2 = " + x)
}
def callByName(x: => Int) = {
println("X1 = " + x)
println("X2 = " + x)
}
}
output
Calling func()
X1 = 1
X2 = 1
---------------------
Calling func()
X1 = 1
Calling func()
X2 = 1
By-name parameters behave like functions; the expression is evaluated every time it is used. So, by-name parameters are in a sense lazy.
2. An example
Here is a simple implementation of a while-like loop construct, called continue
:
code
package com.brown
/**
* Created by BrownWong on 2016/9/29.
*/
object Hello {
def main(args: Array[String]): Unit = {
var count = 0
continue(count < 5) {
println(s"at $count")
count += 1
}
}
@annotation.tailrec
def continue(conditional: => Boolean)(body: => Unit) {
if (conditional) {
body
continue(conditional)(body)
}
}
}
output:
at 0
at 1
at 2
at 3
at 4
Ref
《Programming Scala》
http://stackoverflow.com/questions/13337338/call-by-name-vs-call-by-value-in-scala-clarification-needed