函数参数类型和=>

Pri*_*osK 37 parameters scala declaration

究竟该方法参数的声明意味着什么:

def myFunc(param: => Int) = param
Run Code Online (Sandbox Code Playgroud)

=>上限定义是什么意思?

Tom*_*icz 57

这就是所谓的名字传递.这意味着您传递的函数应该返回,Int但主要用于实现参数的延迟评估.它有点类似于:

def myFunc(param: () => Int) = param
Run Code Online (Sandbox Code Playgroud)

这是一个例子.考虑一个answer函数返回一些Int值:

def answer = { println("answer"); 40 }
Run Code Online (Sandbox Code Playgroud)

还有两个功能,一个是一个Int,另一个是Int 按名称:

def eagerEval(x: Int)   = { println("eager"); x; }
def lazyEval(x: => Int) = { println("lazy");  x; }
Run Code Online (Sandbox Code Playgroud)

现在使用answer以下命令执行它们:

eagerEval(answer + 2)
> answer
> eager

lazyEval(answer + 2)
> lazy
> answer
Run Code Online (Sandbox Code Playgroud)

第一种情况很明显:在eagerEval() answer评估调用之前并打印"answer"字符串.第二种情况更有趣.我们实际上正在传递一个函数lazyEval().第lazyEval一个打印"lazy"并评估x参数(实际上,调用x函数作为参数传递).

也可以看看

  • 我认为你的意思是"按名称呼叫",而不是"按名称传递"或"传递值"(参见语言规范4.6.1) (5认同)
  • 你想要的术语是"按名称传递" - 而不是"按值传递".通过价值传递是完全不同的; 这就是Java用原语做的事情. (3认同)
  • 我现在已经证实了我的怀疑.在'lazyEval()'函数中,省略对name-by-name-defined(=>)参数/函数'x'的内部调用会阻止调用'x'.但是,从'eagerEval()'中省略相同的x调用会导致参数x作为参数传递时不会停止参数x的计算. (2认同)

Wil*_*ger 12

只是为了确保有一个使用正确术语的答案:Scala语言规范使用术语call-by-name:

值参数的类型可以通过=>预先固定,例如x:=> T. 这样的参数的类型是无参数方法类型=> T. 这表示相应的参数不在函数应用程序点评估,而是在函数内的每次使用时进行评估.也就是说,使用call-by-name评估参数.

- Scala语言规范的第4.6.1节


mo-*_*eph 7

要添加Tomasz Nurkiewicz上面的答案,我在()=> Int和=> Int之间遇到的区别是第二个允许使用裸块进行调用:

scala> def myfunc(f : () => Int ) = println("Evaluated: " + f )
myfunc: (f: () => Int)Unit

scala> def myfunc2(f : => Int ) = println("Evaluated: " + f )
myfunc2: (f: => Int)Unit

scala> myfunc({1})
<console>:9: error: type mismatch;
 found   : Int(1)
 required: () => Int
              myfunc({1})
                  ^

scala> myfunc2({1})
Evaluated: 1
Run Code Online (Sandbox Code Playgroud)