Function parameter types and =>

2020-05-11 13:04发布

问题:

What exactly that declaration of method parameter means:

def myFunc(param: => Int) = param

What is meaning of => in upper definition?

回答1:

This is so-called pass-by-name. It means you are passing a function that should return Int but is mostly used to implement lazy evaluation of parameters. It is somewhat similar to:

def myFunc(param: () => Int) = param

Here is an example. Consider an answer function returning some Int value:

def answer = { println("answer"); 40 }

And two functions, one taking Int and one taking Int by-name:

def eagerEval(x: Int)   = { println("eager"); x; }
def lazyEval(x: => Int) = { println("lazy");  x; }

Now execute both of them using answer:

eagerEval(answer + 2)
> answer
> eager

lazyEval(answer + 2)
> lazy
> answer

The first case is obvious: before calling eagerEval() answer is evaluated and prints "answer" string. The second case is much more interesting. We are actually passing a function to lazyEval(). The lazyEval first prints "lazy" and evaluates the x parameter (actually, calls x function passed as a parameter).

See also

  • Scala Returning a void function with 0 parameters, ugly syntax?


回答2:

Just to make sure there is an answer that uses the proper term: the Scala Language Specification uses the term call-by-name:

The type of a value parameter may be prefixed by =>, e.g. x: => T . The type of such a parameter is then the parameterless method type => T . This indicates that the corresponding argument is not evaluated at the point of function application, but instead is evaluated at each use within the function. That is, the argument is evaluated using call-by-name.

-- Section 4.6.1 of the Scala Language Specification



回答3:

To add to Tomasz Nurkiewicz's answer above, the difference I encounter between () => Int and => Int is that the second allows calling with bare blocks:

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