传名函数与传值函数

本文深入探讨Scala中的传值(call-by-value)与传名(call-by-name)调用机制,分析两者在参数传递过程中的不同行为及对效率的影响。通过具体示例展示,帮助读者理解何时使用何种调用方式更为合适。

Scala的解释器在解析函数参数(function arguments)时有两种方式:先计算参数表达式的值(reduce the arguments),再应用到函数内部;或者是将未计算的参数表达式直接应用到函数内部。前者叫做传值调用(call-by-value),后者叫做传名调用(call-by-name)。

传值函数和传名函数

object Add {
def addByName(a: Int, b: => Int) = a + b
def addByValue(a: Int, b: Int) = a + b
}

传名函数和传值函数在编译器中区别:
addByName(2, 2 + 2)
->2 + (2 + 2)
->2 + 4
->6

addByValue(2, 2 + 2)
->addByValue(2, 4)
->2 + 4
->6

可以看出,在进入函数内部前,传值调用方式就已经将参数表达式的值计算完毕,而传名调用是在函数内部进行参数表达式的值计算的。

这就造成了一种现象,每次使用传名调用时,解释器都会计算一次表达式的值。对于有副作用(side-effect)的参数来说,这无疑造成了两种调用方式结果的不同。

因此, 在实际的使用中:
传值调用在进入函数体之前就对参数表达式进行了计算,这避免了函数内部多次使用参数时重复计算其值,在一定程度上提高了效率。

但是传名调用的一个优势在于,如果参数在函数体内部没有被使用到,那么它就不用计算参数表达式的值了。在这种情况下,传名调用的效率会高一点。

package Demo
//传名和传值参数
object Demo01 extends App {

  def time()={

    println("获取时间,单位为毫秒")
    System.nanoTime()//时间毫秒

  }


//传值调用,直接获取参数名中的值放入主函数中    传值调用(call-by-value)
  def delayed(t:Long) ={

    println("在delayed方法内")

    println("参数为"+t)

  }

//  获取时间,单位为毫秒
//  在delayed方法内
//  参数为10874963211520
delayed(time())


//传名调用当遇到参数名的时候 计算参数名中的逻辑    传名调用(call-by-name)
  def delayedd(t : =>Long) = {

    println("在delayed方法内")

    println("参数为" + t)
  }
//
//  在delayed方法内
//  获取时间,单位为毫秒
//  参数为11088250581065

  delayedd(time())

  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值