简体   繁体   English

使用lazy val进行名称调用和call-by-value

[英]call-by-name and call-by-value with lazy val

I would like to know the difference between a variable passed by value, but lazy, and pass a variable by name in Scala. 我想知道一个变量传递的值,但是懒惰,并在Scala中按名称传递一个变量。

I wrote this example to try to show but I do not, how should I do? 我写这个例子试图表明,但我没有,我该怎么办?

def callByValue(x : Unit) = {
x
x
}

def callByName(x : => Unit) = {
    x
    x
}

lazy val j = {println("initializing lazy"); 0}
var i = {println("initializing"); 0}

callByName(i = i + 1)
print(i + "\n")  // "5"

callByValue(j)
print(j + "\n")  // "1"

By "5" you mean, like, 2, right? 用“5”表示,就像2,对吗? And "1" means 0? 而“1”表示0?

Is this one of those Google interview questions? 这是Google面试问题吗?

This shows the closure evaluated twice by the function: 这显示函数的闭包评估两次:

scala> callByName {
     | println("calling")
     | i += 1
     | }
calling
calling

and then 接着

scala> println(i)
4

That's after it was 2. 那是在2之后。

HTH. HTH。

See if this helps. 看看这是否有帮助。

  • val is executed at time of definition val在定义时执行
  • lazy val is executed once but at first time of reference lazy val执行一次但在第一次引用时
  • :=> pass by name is executed everytime at time of reference but not at time of definition (think of it like a function, a function is executed at time of call/reference, not at time when we define a function), :=>按名称传递每次在引用时执行,但不在定义时执行(将其视为函数,函数在调用/引用时执行,而不是在我们定义函数时执行),

     def callByValue(x : Unit) = { xx } def callByName(x : => Unit) = { xx } val i = {println("i"); 0}//print should happen now at time of declaration. i is 0. lazy val j = {println("j"); 0} //no print because {...} will get executed when j is referenced, not at time of definition. val k = {println("k"); 0} //same as case of i, print should happen now. K should be 0 //no special case. A val being passed like a regular function println("k test. K is val") callByValue (k) //no prints as K block is already evaluated. //passing a val to a function by name. The behavior will be same as K because i is already evaluated at time of definition. basically we are passing 0 println("i test. i is val but passed by Name."); callByName(i);//I is passed by name. Thus the block will be executed everytime it is referenced println("j test. It is passed lazy. It will be executed only once when referenced for 1st time") callByValue(j) //prints j once, assigns value 0 to j inside callByValue function. Note that because j is lazy, it the block {print j;0} is evaluated once when j was referenced for first time. It is not executed everytime j was referenced. println("test l") callByName({println("l");0});//l is passed by name. Thus the block will be executed everytime it is referenced 

    println("test l again") callByValue({println("l");0});//l is passed by value. println(“再次测试l”)callByValue({println(“l”); 0}); // l按值传递。 Thus the block will be executed once 因此该块将被执行一次

Output 产量

i <- when i was defined. val i = {println("i"); 0}
k <- when k was defined. {println("k"); 0}
k test. K is val <- no further prints of 'k' as the {println("k"); 0} has already been evaluated
i test. i is val but passed by Name. <- no furhter prints of 'i' as {println("i"); 0} is already evaluated
j test. It is passed lazy. It will be executed only once when referenced for 1st time
j <- note j is printed now instead of time of definition

test l
l <- we passed {print(l);0}. It will get executed everytime l is referenced. Thus two prints corresponding to {x;x} code of call by name
l
test l again
l <- only one print when {print(l);0} was passed by value

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM