为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

小唯快跑啊 2019-07-26 15:14:14
在Scala中按名称调用与按值调用,需要澄清据我所知,在Scala中,函数可以被称为按价值或有名无实例如,给定以下声明,我们知道如何调用该函数吗?声明:def  f (x:Int, y:Int) = x;打电话f (1,2)f (23+55,5)f (12+3, 44*11)请问有什么规定?
查看完整描述

3 回答

?
杨魅力

TA贡献1811条经验 获得超6个赞

您给出的示例只使用了按值调用,所以我将给出一个新的、更简单的示例,它显示了不同之处。

首先,假设我们有一个有副作用的函数。此函数输出一些内容,然后返回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()只发生过一次。然而,在点名版中,副作用发生了两次.

这是因为按值调用函数在调用函数之前计算传入表达式的值,因此值每次都会被访问。但是,按名调用函数。重算每次访问传入表达式的值。




查看完整回答
反对 回复 2019-07-27
?
qq_花开花谢_0

TA贡献1835条经验 获得超7个赞

以下是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
结果在相同的步骤中达到。



查看完整回答
反对 回复 2019-07-27
?
慕村225694

TA贡献1880条经验 获得超4个赞

要在上面的评论中迭代@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

 


查看完整回答
反对 回复 2019-07-27
  • 3 回答
  • 0 关注
  • 556 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信