`
zhouchaofei2010
  • 浏览: 1085886 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Scala“call by name“和 “call by value” 比较

阅读更多
首先解释下call by name 的作用:
all by name : 为了避免在调用时用() => 符号,以为这有点丑陋: Omit the (), but not the => in the parameter declaration 
比如没有call by name 
def runInThread(block: () => Unit) {
  new Thread {
    override def run() { block() }
  }.start()
}
这样调用的时候是这样的 runInThread { () => println("Hi"); Thread.sleep(10000); println("Bye") }   必须要有() =>,丑陋
 
应用call by name,就可以这样声明函数的参数
def runInThread(block: => Unit) {
  new Thread {
    override def run() { block }
  }.start()
}
调用的时候就变的简单优雅: runInThread { println("Hi"); Thread.sleep(10000); println("Bye") }
 
 
两者之间的比较:
Call by name :传给函数/方法M的参数是另外一个参数函数,该参数函数在函数体内调用时执行
call by value : 传给函数的参数是个值,如果是个表达式或者是另外一个参数函数,则要先计算出表达式的值或者是要先得到参数函数执行后的返回值
 
《Programming in Scala, 2nd Edition》在 9.5 By-name parameters 一节出给出一个例子解释
 
代码如下:
 
 
object bynameparameters extends App {
var assertionsEnabled = false
//Call by name
def byNameAssert(predicate: => Boolean) =
if (assertionsEnabled && !predicate)
throw new AssertionError
 
//call by value 
def boolAssert(predicate: Boolean) =
if (assertionsEnabled && !predicate)
throw new AssertionError
//boolAssert(3 /0 == 0) // java.lang.ArithmeticException: / by zero
 byNameAssert(3 / 0 == 0) //will not yield an exception:

}

 
 
当执行boolAssert(3 /0 == 0) 时,会先算3 /0 == 0表达式,于是抛出异常
 
但是执行byNameAssert(3 / 0 == 0),3 / 0 == 0,会隐式转换成一个函数predicate给byNameAssert,因为assertionsEnabled = false,所以在if语句判断中永远不会执行predicate方法,所以不会产生异常
 
 
另外在stackoverflowe 上有篇关于“call by name“和 “call by value”的解释不错,可以参考
1
3
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics