Scala 中按名称调用与按值调用,需要澄清 [英] Call by name vs call by value in Scala, clarification needed
问题描述
据我所知,在 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屋!