匿名 函数
1958
用途 [编辑]
排 序 [编辑]
尝试
a = [10, '10', 10.0]
a.sort(lambda x,y: cmp(x.__class__.__name__, y.__class__.__name__))
print a
[10.0, 10, '10']
10.0
float
”,10
int
”而 '10'
str
”,float
”“int
”,str
”。
该示
lambda x,y: cmp(...)
该匿x
y
,cmp()
a = ['three', 'two', 'four']
a.sort(lambda x,y: cmp(len(x), len(y)))
print a
['two', 'four', 'three']
语言列 表 [编辑]
语言 | 备注 | |
---|---|---|
ActionScript | ||
C | ||
C# | ||
C++ | 从C++11开始 | |
Clojure | ||
Curl | ||
D | ||
Delphi | 从Delphi 2009开始 | |
Dylan | ||
Erlang | ||
F# | ||
Frink | ||
Go | ||
Haskell | ||
Java | 从Java 8开始 | |
JavaScript | ||
Kotlin | ||
Lisp | ||
Logtalk | ||
Lua | ||
Mathematica | ||
Matlab | ||
ML语言 (Objective Caml, Standard ML, etc.) |
||
Octave | ||
Object Pascal | ||
Objective-C (Mac OS X 10.6+) | ||
Pascal | ||
Perl | ||
PHP | 从PHP 5.3.0开始 | |
Python | Python | |
R | ||
Ruby | Ruby | |
Rust | Rust | |
Scala | ||
Scheme | ||
Smalltalk | Smalltalk | |
Tcl | ||
Visual Basic .NET v9 | ||
Visual Prolog v 7.2 | ||
Vala |
示 例 [编辑]
Python[编辑]
Python
# 以下 两种相等 同
# 1.不 使用 匿名 函数
def f(x):
return x * x
# 2.使用 匿名 函数
lambda x: x * x
JavaScript[编辑]
JavaScript
alert((function(x){
return x*x;
})(10)); // 提示 100
javascript:document.title=location.href;
javascript:(function(){document.title=location.href;})();
javascript:var f = function(){document.title=location.href;}; f();
PHP[编辑]
PHP 4.0.1
4.0.1 至 5.3[编辑]
PHP 4.0.1create_function
$foo = create_function('$x', 'return $x*$x;');
$bar = create_function("\$x", "return \$x*\$x;");
echo $foo(10);
5.3[编辑]
PHP 5.3Closure
类,以及__invoke()
[6]。LambdaClosure
实例,就像
$x = 3;
$func = function($z) { return $z *= 2; };
echo $func($x); // 输出结果为6
$func
Closure
类的echo $func()
则相$func->__invoke($z)
。PHP 5.3
虽然PHP 5.3
$x = 3;
$func = function() use(&$x) { $x *= 2; };
$func();
echo $x; // 输出结果为6
$func
$x
(&$x),
C++[编辑]
C++ 98/03[编辑]
C++ 98/03标准并不
C++ 11[编辑]
C++11标准
[capture] (parameters) mutable exception attribute -> return_type { body }
必须
lambda
参 数 不能 有 缺 省 值不能 有可 变长参 数列 表 不能 有 无名参 数
如果lambda
如果
[capture](parameters){body}
[](int x, int y) { return x + y; } // 從 return語句 中 隱 式 獲得 的 返 回 值類型
[](int& x) { ++x; } // 沒 有 return語句 -> lambda函數 的 返 回 值為void
[]() { ++global_x; } // 沒 有 參 數 ,僅僅 是 訪問 一 個 全局 變量
[]{ ++global_x; } // 與 前者 相 同 ,()可 以被省略
decltype(x+y)
。如果lambdareturn expression
,decltype
[](int x, int y) -> int { int z = x + y; return z; }
z
,-> void
lambda[
]
operator()
[] // 沒 有 定義 任 何 變量 ,但 必须列 出 空 的 方 括 号 。在 Lambda表 達 式 中 嘗試使用 任 何 外部 變量 都會 導 致編譯 錯誤 。
[x, &y] // x是 按值傳 遞,y是 按引用 傳 遞
[&] // 任 何 被 使用 到 的 外部 變量 都 按引用 傳 入 。
[=] // 任 何 被 使用 到 的 外部 變量 都 按值傳 入 。
[&, x] // x按值傳 入 。其它變量 按引用 傳 入 。
[=, &z] // z按引用 傳 入 。其它變量 按值傳 入 。
std::vector<int> some_list{ 1, 2, 3, 4, 5 };
int total = 0;
std::for_each(begin(some_list), end(some_list),
[&total](int x) { total += x; }
);
this
lambda
函数 参 数 局部 声明 的 变量- 类数
据 成 员:要求 lambda表 达式声明 在 类成员函数 中 ,对象的 this指 针必需显式 捕 获声明 。 具有 静 态存储期的 变量(如全局 变量)。一般 情 况下,lambda是 用 来 捕 获局部 变量的 ,如果用 其来捕 获全局 变量或 者 静 态变量 ,那 么编译器会 报warning被 捕 获的外部 变量- 显式
捕 获的变量 - 隐式
捕 获的变量,使用 默 认捕获模式 (传值或 引用 )来 访问。
- 显式
lambdastd::function
auto
关键
#include <functional>
#include <vector>
#include <iostream>
double eval(std::function <double(double)> f, double x = 2.0)
{
return f(x);
}
int main()
{
std::function<double(double)> f0 = [](double x){return 1;};
auto f1 = [](double x){return x;};
decltype(f0) fa[3] = {f0,f1,[](double x){return x*x;}};
std::vector<decltype(f0)> fv = {f0,f1};
fv.push_back ([](double x){return x*x;});
for(int i=0;i<fv.size();i++)
std::cout << fv[i](2.0) << std::endl;
for(int i=0;i<3;i++)
std::cout << fa[i](2.0) << std::endl;
for(auto &f : fv)
std::cout << f(2.0) << std::endl;
for(auto &f : fa)
std::cout << f(2.0) << std::endl;
std::cout << eval(f0) << std::endl;
std::cout << eval(f1) << std::endl;
std::cout << eval([](double x){return x*x;}) << std::endl;
return 0;
}
auto a_lambda_func = [](int x) { /*...*/ };
void (* func_ptr)(int) = a_lambda_func;
func_ptr(4); //calls the lambda.
C++14[编辑]
C++11
- lambda
捕 获的是 局部 变量或 形 参 ,不 管 是 按值还是按引用 捕 获,这些都 是 具 名 的 左 值对象 。而右值对象 是 匿名 对象,无法被 捕 获。 - 按值捕获时,
左 值是被 复制到 闭包中 的 。如果被 捕 获的对象是 个只移 动类型 的 对象时,因 其无法被 复制,就会出 错。 - 如果
被 捕 获的对象如果是 一个占用内存较大的对象时,按值捕获显然 效率 很低。
C++14
C++14还允许lambdaauto
关键operator()
auto a_lambda_func = [data1=101](int x) { /*...*/ }; //广义捕获,实质上 是 在 函数 对象中 增加 了 数 据 成 员data1并初始 化
auto ptr = std::make_unique<int>(10); //See below for std::make_unique
auto lambda1 = [ptr = std::move(ptr)] {return *ptr;}
//大 致等效 于:
auto lambda2 = [ptr = std::make_unique<int>(10)] {return *ptr;}
auto lambda3 = [](auto x, auto y) {return x + y;} //lambda函数 的 形 参 类型为auto
struct unnamed_lambda //这相当 于函数 对象:
{
template<typename T, typename U>
auto operator()(T x, U y) const {return x + y;}
};
auto lambda4 = [](auto&&... params) //可 变参数 的 函数 模 板
{
return (foo(std::forward<decltype(params)>(params)...));
}
Visual Basic.NET[编辑]
Dim func1=Function(i As integer) i+10
Dim action = sub()
End Sub
Dim func2 = Function()
End Function
lambda
参考 资料[编辑]
- ^ Anonymous functions. [2014-04-27]. (
原始 内容 存 档于2014-03-27) (英 语).Anonymous functions, also known as closures, allow the creation of functions which have no specified name. They are most useful as the value of callback parameters, but they have many other uses.
- ^ 2.0 2.1 5.1.2 Lambda expressions. ISO/IEC 14882:2011. [2014-04-27]. (
原始 内容 存 档于2014-04-27) (英 语).Lambda expressions provide a concise way to create simple function objects.
- ^ Lambda expressions and closures for C++ (PDF). V Samko; J Willcock, J Järvi, D Gregor, A Lumsdaine. 2006-02-26 [2010-06-01]. (
原始 内容 存 档 (PDF)于2011-07-28). - ^ Java 7 Features. Sun Microsystems. 2010-02-09 [2010-11-21]. (
原始 内容 存 档于2012-02-07). - ^ http://php.net/create_function (页面
存 档备份,存 于互联网档案 馆) the top of the page indicates this with "(PHP 4 >= 4.0.1, PHP 5)" - ^
存 档副本 . [2011-08-13]. (原始 内容 存 档于2011-07-24). - ^
存 档副本 . [2011-08-13]. (原始 内容 存 档于2011-07-24). - ^ Chapter 16. Boost.Lambda - 1.55.0. [2014-04-27]. (
原始 内容 存 档于2014-04-27) (英 语). - ^ 该标
准 文 档可以在ISO/IEC 14882:2011 - Information technology -- Programming languages -- C++ (页面存 档备份,存 于互联网档案 馆)购买,或 者 可 参看 2012年 一月份的标准草案文件N3337 (页面存 档备份,存 于互联网档案 馆),第 5.1.2节的Lambda expressions - ^ MSDN: In C++14, you can introduce and initialize new variables in the capture clause, without the need to have those variables exist in the lambda function’s enclosing scope. The initialization can be expressed as any arbitrary expression; the type of the new variable is deduced from the type produced by the expression. One benefit of this feature is that in C++14 you can capture move-only variables (such as std::unique_ptr) from the surrounding scope and use them in a lambda.