迷茫2017-04-17 14:37:30
The question asked about other languages, which is too broad, because there are so many programming languages, including traditional functions like C language, functions that cannot exist independently like Java, and different forms of various scripting languages. function.
But in a language where functions are first-class citizens, functions are required to do this
Functions can exist independently and can be executed anywhere
The scope of the function is lexical scope and can capture external variables
A function can be returned from another function or used as a parameter of another function (higher-order function)
After a function is generated from another function, the referenced scope is still accessible instead of being destroyed
In many scripting languages and emerging languages, most functions have the above characteristics.
Regarding the issue of closure capture in different languages, you can refer to an article I wrote before https://zhuanlan.zhihu.com/p/...
Let’s talk about C++. C++ has four things that can be called
Function
Function pointer
Classes that overload the () operator
lambda
The types of these four things are different, but they can all be used to execute functions, and they are all in the same form as func()
.
Function and function pointer can be converted to each other under certain circumstances. It exists in C language, but it has some problems that are difficult to solve, including
Function types are difficult to write and read
State cannot be saved inside the function, and there is no way to capture outer variables
A class that overloads the () operator is a functor writing method provided by C++, which can implement many methods
class Test{
public:
Test(int a):_a(a){}
int operator ()(int b){
return _a+b;
}
private:
int _a;
};
Just use this:
Test sum1 = Test(1);
std::cout << sum1(10) << '\n';
Test sum2 = Test(10);
std::cout << sum2(10) << '\n';
You can see that both sum1 and sum2 save a state internally, and then behave differently. This is something that ordinary functions and function pointers cannot do.
However, a major disadvantage of classes that overload the () operator is that they are not lightweight enough. There is a gap between them and functions/function pointers in terms of space usage and execution efficiency.
C++11 introduced lambda, a typical lambda is like this
int a = 10;
auto func = [&a](int b){return a+b;};
std::cout << func(10) << '\n';
a = 20;
std::cout << func(10) << '\n';
You can see that lambda can easily capture variables and achieve closure effects, so we can use lambda in many situations to replace classes that overload the () operator.
However, lambda also has limitations. First of all, its type cannot be written manually, which means that for the same two lambdas, its type is different
auto func = [&a](int b){return a+b;};
auto func2 = [&a](int b){return a+b;};
std::cout << (typeid(func).name() != typeid(func2).name()) << '\n';
So we can only use auto when defining, and if we want to store lambda in a vector, list, etc. container, we must use the packaging class std::function, which is essentially a generic template class , the () operator is also overloaded
std::function<int(int)> func3 = func;
After using std::function, the lightweight advantage of lambda disappears, but sometimes it has to be done.