Scala 中按名称调用与按值调用,需要澄清 [英] Call by name vs call by value in Scala, clarification needed

查看:17
本文介绍了Scala 中按名称调用与按值调用,需要澄清的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我所知,在 Scala 中,一个函数可以被调用

As I understand it, in Scala, a function may be called either

  • 按值或
  • 按名字

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

For example, given the following declarations, do we know how the function will be called?

声明:

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

打电话

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

请问规则是什么?

推荐答案

您给出的示例仅使用按值调用,因此我将给出一个新的、更简单的示例来说明不同之处.

The example you have given only uses call-by-value, so I will give a new, simpler, example that shows the difference.

首先,假设我们有一个有副作用的函数.这个函数打印出一些东西,然后返回一个 Int.

First, let's assume we have a function with a side-effect. This function prints something out and then returns an Int.

def something() = {
  println("calling something")
  1 // return value
}

现在我们将定义两个接受 Int 参数的函数,除了一个以按值调用样式(x:Int) 和另一个按名称调用样式 (x: => Int).

Now we are going to define two function that accept Int arguments that are exactly the same except that one takes the argument in a call-by-value style (x: Int) and the other in a call-by-name style (x: => Int).

def callByValue(x: Int) = {
  println("x1=" + x)
  println("x2=" + x)
}

def callByName(x: => Int) = {
  println("x1=" + x)
  println("x2=" + x)
}

现在当我们用我们的副作用函数调用它们时会发生什么?

Now what happens when we call them with our side-effecting function?

scala> callByValue(something())
calling something
x1=1
x2=1

scala> callByName(something())
calling something
x1=1
calling something
x2=1

所以你可以看到,在 call-by-value 版本中,传入函数调用(something())的副作用只发生了一次.然而,在 call-by-name 版本中,副作用发生了两次.

So you can see that in the call-by-value version, the side-effect of the passed-in function call (something()) only happened once. However, in the call-by-name version, the side-effect happened twice.

这是因为按值调用函数在调用函数之前计算传入表达式的值,因此每次访问相同值.相反,每次访问时,按名称调用函数都会重新计算传入表达式的值.

This is because call-by-value functions compute the passed-in expression's value before calling the function, thus the same value is accessed every time. Instead, call-by-name functions recompute the passed-in expression's value every time it is accessed.

这篇关于Scala 中按名称调用与按值调用,需要澄清的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆