匿名函数
在计算机编程中,匿名函数(英语:anonymous function)是指一类无需定义标识符(函数名)的函数或子程序,普遍存在于多种编程语言中。
1958年LISP首先采用匿名函数,自此之后,越来越多编程语言陆续采用,主流的编程语言如PHP[1]也在不久前采用。其中在JavaScript中的匿名函数最为人熟悉。[來源請求]
目录 |
用途 [编辑]
排序 [编辑]
尝试将类按名称排序:
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表达式:
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 | 在有clang和llvm的compiler-rt程序库的环境下支持 | |
| C# | ||
| C++ | 从C++11开始支持[2] | |
| Clojure | ||
| Curl | ||
| D | ||
| Delphi | 从Delphi 2009开始支持 | |
| Dylan | ||
| Erlang | ||
| F# | ||
| Frink | ||
| Go | ||
| Haskell | ||
| Java | 计划从Java 8或更后期的版本开始支持[3] | |
| JavaScript | ||
| Lisp | ||
| Logtalk | ||
| Lua | ||
| Mathematica | ||
| Matlab | ||
| ML语言 (Objective Caml, Standard ML, etc.) |
||
| Octave | ||
| Object Pascal | 原生支持匿名函数,其正式名称为“匿名方法”(anonymous method)。Oxygene Object Pascal也支持匿名函数。 | |
| Objective-C (Mac OS X 10.6+) | 称作“块”(block) | |
| Pascal | ||
| Perl | ||
| PHP | 从PHP 5.3.0开始支持真匿名函数,之前则只支持部分匿名函数 | |
| Python | Python用lambda语法定义匿名函数,只需用表达式而无需声明 | |
| R | ||
| Ruby | Ruby的匿名函数源自Smalltalk,也同样叫“块”(block)。 | |
| Scala | ||
| Scheme | ||
| Smalltalk | Smalltalk的匿名函数称为“块”(block) | |
| Visual Basic .NET v9 | ||
| Visual Prolog v 7.2 | ||
| Vala |
示例 [编辑]
JavaScript [编辑]
JavaScript支持匿名函数。
alert((function(x){ return x*x; })(10)); // 提示100
小书签也经常使用这种结构,例如下面的一个小书签就将当前网页的标题显示为其URL:
javascript:document.title=location.href;
然而,由于该赋值语句返回了一个值(即URL本身),很多浏览器会同时创建一个新的页面显示这个值。
取而代之,下面的匿名函数就可以做到不返回任何值:
javascript:(function(){document.title=location.href;})();
第一对圆括号中的函数(“(function(){document.title=location.href;})”)用作声明一个匿名函数,而最后的一对圆括号则用来执行这个函数。同等用法有:
javascript:var f = function(){document.title=location.href;}; f();
PHP [编辑]
PHP 4.0.1之前不支持匿名函数[4]。
4.0.1 至 5.3 [编辑]
PHP 4.0.1新增加了create_function函数,这是匿名函数的雏形。该函数能创建一个随机命名的新函数并以字符串形式返回新函数的函数名。
$foo = create_function('$x', 'return $x*$x;'); $bar = create_function("\$x", "return \$x*\$x;"); echo $foo(10);
要注意的是,新函数本身及其变量都要放在单引号里面,如果要放在双引号之内,美元符号“$”则需要转码成为“\$”。
5.3 [编辑]
PHP 5.3新增加了Closure类,以及能使类的实例可被调用的“魔术方法”__invoke()[5]。Lambda函数都是编译器的一种“花招”[6],它能产生新的能被调用的Closure实例,就像函数能被调用一样。
$x = 3; $func = function($z) { return $z *= 2; }; echo $func($x); // 输出结果为6
上述例子中的$func是Closure类的一个实例,而echo $func()则相当于是$func->__invoke($z)。PHP 5.3模仿使用匿名函数,但并非支持真匿名函数,因为PHP的函数仍非第一类函数。
虽然PHP 5.3支持闭包,但还需要像这样明确标识其变量:
$x = 3; $func = function() use(&$x) { $x *= 2; }; $func(); echo $x; // 输出结果为6
$func引用了变量$x(&$x),在调用的时候就会修改原来的$x,其结果在函数以外的地方也是可见的。
参考资料 [编辑]
- ^ Anonymous functions. [2011-02-17]. "Anonymous functions, also known as closures, allow the creation of functions which have no specified name."
- ^ Lambda expressions and closures for C++. V Samko; J Willcock, J Järvi, D Gregor, A Lumsdaine. 2006-02-26 [2010-06-01].
- ^ Java 7 Features. Sun Microsystems. 2010-02-09 [2010-11-21].
- ^ http://php.net/create_function the top of the page indicates this with "(PHP 4 >= 4.0.1, PHP 5)"
- ^ http://wiki.php.net/rfc/closures
- ^ http://wiki.php.net/rfc/closures#zend_internal_perspective