Scala has both functions and methods. In most cases, we can ignore the differences between them. But sometimes we must understand their differences.
Methods in Scala are like methods in Java; methods are part of a class. A method has a name, a type signature, sometimes annotations on the method, and the functional implementation code (bytecode) of the method.
Functions in Scala are complete objects. Scala uses 22 traits to abstract the concept of functions. These 22 traits range from Function1 to Function22:
As shown in the figure above, Function10 represents: a function with 10 formal parameters and a return value of R (covariant).
Functions in Scala are actually objects of classes that inherit these traits. For example, we define a function through a function literal:
In fact, the above function definition is equivalent to the following definition:
Since Function2 is a trait, it cannot be directly instantiated with new. The abovenew Function2[Int,Int,Int](){}is actually defining and instantiating an object of a class that implements the Function2 trait.
apply is syntactic sugar in Scala: calling obj() on an object obj, the Scala compiler converts it to obj.apply(); calling clazz() on a class clazz, the Scala compiler converts it to clazz_company_obj.apply(), where clazz_company_obj is the companion object of clazz.
The specific differences are summarized as follows:
1. A method cannot exist as a standalone expression (except for methods with no parameters), but a function can. For example:
In the above example, we first defined a method m, and then defined a function f. Then we use the function name (function value) as the final expression. Since f itself is
an object (an object implementing the FunctionN trait), this usage is completely correct. But if we use the method name as the final expression, it will cause an error.
2. A function must have a parameter list, while a method can have no parameter list.
In the above example, the m1 method accepts zero parameters, so the parameter list can be omitted. But a function cannot omit the parameter list.
3. A method name is a method call, while a function name only represents the function object itself.
This is easier to understand. Because the variable that holds the function literal (also called the function name or function value) is itself an object of a class implementing the FunctionN trait. To call the object's apply method, you need to use the obj() syntax. Therefore, adding parentheses after the function name is how you call the function. As follows:
4. Where a function is needed, if a method is passed, ETA expansion (converting a method to a function) is automatically performed.
If we directly assign a method to a variable, an error will be reported. If we specify the variable's type as a function, then it can pass compilation. As follows:
Of course, we can also force a method to be converted to a function, which uses Scala's partially applied functions:
5. A by-name parameter is essentially a method.
A by-name parameter is essentially a method with an empty parameter list. As follows:
The above code actually defines a method m1, and m1's parameter is a by-name parameter (method). Since for a method with no parameters, the method name is the method call , List(x, x) actually performs two method calls.
BecauseList(x,x)two method calls are performed, two different values are obtained.
If we slightly modify the definition of m1 and cache x first, the result will be very different from before.
Original article: https://blog.csdn.net/u012302488/article/details/50543661