在Scala中按名称调用与按值调用,需要澄清

在Scala中按名称调用与按值调用,需要澄清

据我所知,在Scala中,函数可以被称为

  • 按价值或
  • 有名无实

例如,给定以下声明,我们知道如何调用该函数吗?

声明:

def  f (x:Int, y:Int) = x;

打电话

f (1,2)f (23+55,5)f (12+3, 44*11)

请问有什么规定?



小唯快跑啊
浏览 557回答 3
3回答

杨魅力

您给出的示例只使用了按值调用,所以我将给出一个新的、更简单的示例,它显示了不同之处。首先,假设我们有一个有副作用的函数。此函数输出一些内容,然后返回Int.def something() = {   println("calling something")   1 // return value}现在我们将定义两个接受Int参数完全相同的参数,但以按值调用的方式接受参数(x: Int)和另一个按名字调用的方式(x: => Int).def callByValue(x: Int) = {   println("x1=" + x)   println("x2=" + x)}def callByName(x: => Int) = {   println("x1=" + x)   println("x2=" + x)}现在,当我们用我们的副作用函数调用它们时,会发生什么呢?scala> callByValue(something())calling something x1=1x2=1scala> callByName(something())calling something x1=1calling something x2=1因此您可以看到,在按值调用版本中,传入函数调用的副作用(something()只发生过一次。然而,在点名版中,副作用发生了两次.这是因为按值调用函数在调用函数之前计算传入表达式的值,因此同值每次都会被访问。但是,按名调用函数。重算每次访问传入表达式的值。

qq_花开花谢_0

以下是MartinOdersky的一个例子:def test (x:Int, y: Int)= x*x我们希望检查评估策略,并确定在这些条件下哪种策略更快(步骤更少):test (2,3)按值调用:测试(2,3)->2*2->4按姓名呼叫:test(2,3)->2*2->4在这里,用相同数目的步骤达到结果。test (3+4,8)按值调用:测试(7,8)->7*7->49点名:(3+4)(3+4) -> 7(3+4)-> 7*7 ->49在这里,按值调用更快。test (7,2*4)按值调用:测试(7,8)->7*7->49点名:7*7->49在这里按名字叫更快test (3+4, 2*4)按值调用:test(7,2*4)->test(7,8)->7*7->49点名:(3+4)(3+4) -> 7(3+4) -> 7*7 -> 49结果在相同的步骤中达到。

慕村225694

要在上面的评论中迭代@Ben的观点,我认为最好把“逐名”看作是语法糖。解析器只是将表达式封装在匿名函数中,以便在以后使用时调用它们。实际上,而不是定义def callByName(x: => Int) = {   println("x1=" + x)   println("x2=" + x)}和跑步:scala> callByName(something())calling something x1=1calling something x2=1你也可以写:def callAlsoByName(x: () => Int) = {   println("x1=" + x())   println("x2=" + x())}并按以下方式运行,效果相同:callAlsoByName(() => {something()})calling something x1=1calling something x2=1 
打开App,查看更多内容
随时随地看视频慕课网APP