Differences Between Methods and Functions in Scala
Category Programming Technology
>
Scala has both methods and functions, and in most cases, we don't need to distinguish between them. However, there are times when understanding their differences is crucial.
Methods in Scala are similar to those in Java; they are part of a class. Methods have names, type signatures, sometimes annotations, and the implementation code (bytecode).
Functions in Scala are complete objects. Scala abstracts the concept of functions with 22 traits, ranging from Function1 to Function22:
As shown in the diagram, Function10 represents a function with 10 parameters and a return value of R (covariant).
A function in Scala is essentially an object of a class that inherits these traits. For example, defining a function using a function literal is equivalent to:
Since Function2 is a trait and cannot be directly instantiated, new Function2[Int, Int, Int]()
actually defines and instantiates an object of a class that implements the Function2 trait.
apply
is syntactic sugar in Scala: calling obj()
on an object obj
is translated by the Scala compiler to obj.apply()
; calling clazz()
on a class clazz
is translated to clazz_companion_obj.apply()
, where clazz_companion_obj
is the companion object of clazz
.
Specific differences can be summarized as follows:
- Methods cannot exist as standalone expressions (except for methods with no parameters), whereas functions can.
In the example above, we first define a method m
and then a function f
. We then use the function name (function value) as the final expression. Since f
is itself an object (an object that implements the FunctionN trait), this usage is correct. However, using the method name as the final expression will result in an error.
- Functions must have a parameter list, whereas methods can have no parameter list.
In the example above, method m1
takes zero parameters, so the parameter list can be omitted. Functions cannot omit the parameter list.
- The method name is a method call, whereas the function name represents the function object itself.
This is easy to understand. Since the variable that holds the function literal (also known as the function name or function value) is itself an object of a class that implements the FunctionN trait, to call the apply
method of the object, we need to use the obj()
syntax. Therefore, adding parentheses after the function name is how we call the function.
- When a function is required, passing a method will automatically perform ETA expansion (converting the method to a function).
If we directly assign a method to a variable, it will result in a compilation error. If we specify the variable's type as a function, it will compile successfully, as shown below:
We can also force a method to be converted to a function using partial application functions in Scala:
- By-name parameters are essentially methods.
A by-name parameter is essentially a method with an empty parameter list, as shown below:
The above code actually defines a method m1
, where the parameter is a by-name parameter (method). Since for methods with no parameters, the method name is the method call, List(x, x)
actually performs two method calls.
Since List(x, x)
performs two method calls, it results in two different values.
If we slightly modify the definition of function m1
to cache x
first, the result will be significantly different.
>
Original: https://blog.csdn.net/u012302488/article/details/50543661