本质的区别就是执行期不同,普通参数的表达式传参时已经开始执行,而byName的高阶函数在方式执行体中按定义顺序执行,有可能被短路。
def paramterMethod(b:Boolean){
if(false && b) println("hello")
}
paramterMetho(5 > 3)在传参时5 > 3一定已经运行,如果改成 1/0==0肯定抛出错误。
def funcMethod(b:=>Boolean){
if(false && b) println("hello")
}
paramterMetho(5 > 3)在传参时传的是一个返回Boolean的函数值,然后在if(false && b)时因为被适中,这个byName的函数并没被调用,所以5>3这个表达式
并没有作为参数传给那个byName的函数。
完整的例子:
object Main extends App {
def parameterMethod(b: Boolean) {
if (false && b) println("Hello!")
}
def funcMethod(b: => Boolean) {
if (false && b) println("Hello!")
}
funcMethod(1 / 0 == 0)
parameterMethod(1 / 0 == 0)
}
运行结果:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Main$delayedInit$body.apply(Main.scala:12)
at scala.Function0$class.apply$mcV$sp(Function0.scala:34)
at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
at scala.App$$anonfun$main$1.apply(App.scala:60)
at scala.App$$anonfun$main$1.apply(App.scala:60)
at scala.collection.LinearSeqOptimized$class.foreach(LinearSeqOptimized.scala:59)
at scala.collection.immutable.List.foreach(List.scala:76)
at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:30)
at scala.App$class.main(App.scala:60)
at Main$.main(Main.scala:1)
at Main.main(Main.scala)
第12行正是 parameterMethod(1 / 0 == 0)