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”的解释不错,可以参考
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值