實現一個簡單的匿名函數:php
$func = function() { echo "this is a func\n"; };
上面就是一個簡單的匿名函數,定義一個函數體,將函數體賦值給一個變量(php5.3以後支持該寫法)。golang
一、當作參數傳遞:
<?php // 定義一個匿名函數,賦值給$func $func = function($param) { var_dump($param); }; // 將匿名函數做爲參數傳入,並調用該參數 function dFunc($func, $param) { $func($param); } dFunc($func, '123'); // 輸出:string(3) "123"
二、將匿名函數返回:
<?php // 定義一個函數,在該函數中將內部的匿名函數返回 function cFunc($param) { $func = function($param1) use ($param) { echo "params:".$param1." ".$param; }; return $func; } // 獲取並調用匿名函數 $rCFunc = cFunc("123"); $rCFunc("456"); // params:456 123
閉包: 閉包是詞法做用於的體現,一個持有外部環境自由變量的函數就是閉包。閉包體現的是在程序運行過程當中,由 「不肯定」變爲「 肯定」 的過程。捕獲外部變量: 在PHP中對捕獲這一動做有了更清晰的表現,使用use關鍵字。如上面例2。閉包
在上面的例2中,匿名函數$func經過use關鍵字捕獲了外部的自由變量$param,在調用時經過傳入cFunc()函數的參數123($param此時會變爲「肯定」狀態),進而調用匿名函數時輸出「params:456 123」。函數
use引入的是自由變量的副本。this
例如: <?php /* 輸出結果: 匿名函數執行前:p1:p1 匿名函數內修改後:p1:p2 匿名函數執行完:p1:p1 */ function f1() { $p1 = "p1"; echo "匿名函數執行前:p1:$p1\n"; $func = function() use ($p1) { $p1 = "p2"; echo "匿名函數內修改後:p1:$p1\n"; }; $func(); echo "匿名函數執行完:p1:$p1\n"; } f1();
golang閉包: 在golang中一樣經過匿名函數實現了閉包,和PHP不一樣的是,golang中的閉包是默認會引入上下文的自由變量,且引入的地址,即在閉包函數內部修改變量會在函數外部生效。
用於表明匿名函數類。在PHP中定義一個閉包函數其實就是一個Closure類的實例。
<?php /* 輸出: object(Closure)#1 (0) { } */ $func = function() {}; var_dump($func);
類摘要
Closure { /* 方法 */ __construct ( void ) public static bind ( Closure $closure , object $newthis [, mixed $newscope = 'static' ] ) : Closure public bindTo ( object $newthis [, mixed $newscope = 'static' ] ) : Closure }
複製一個閉包,綁定指定的$this對象和類做用域,返回一個新的匿名函數code
參數說明:對象
- closure: 須要綁定的匿名函數。
- newthis: 須要綁定到匿名函數的對象,或者 NULL 建立未綁定的閉包。(理解:能夠選擇是否將匿名函數綁定到一個類對象,若綁定到了一個類對象,則能夠在匿名函數內使用
$this
,不然不可以使用。)- newscope: 想要綁定給閉包的類做用域,或者 'static' 表示不改變。若是傳入一個對象,則使用這個對象的類型名。 類做用域用來決定在閉包中 $this 對象的 私有、保護方法 的可見性。(理解:若是傳入一個類,則能夠訪問類的static、private、protected屬性,不然只能訪問public屬性。)
簡單理解:能夠簡單理解爲將該匿名函數綁定到一個類或實例。根據參數的不一樣,能夠訪問不一樣的類的屬性。作用域
<?php class A{ private static $_cat = 'cat'; private $_dog = 'dog'; public $pig = 'pig'; } $cat = static function() { var_dump(A::$_cat); }; $dog = function() { var_dump($this->_dog); }; $pig = function() { var_dump($this->pig); }; // 傳入null,不可以使用$this,但傳入A類,則能夠訪問static等 $bindCat = Closure::bind($cat, null, 'A'); echo "bind cat\n"; $bindCat(); // 傳入new A()對象,A類,可使用$this訪問私有屬性。 $bindDog = Closure::bind($dog, new A(), 'A'); echo "bind dog\n"; $bindDog(); // 爲傳入類對象,不可以使用$this $bindDog2 = Closure::bind($dog, null, 'A'); echo "bind dog2\n"; $bindDog2();
輸出:
bind cat
string(3) "cat"
bind dog
string(3) "dog"
bind dog2
Fatal error: Using $this when not in object context
Closure::bind()的非靜態形式。string
- PHP經過匿名函數實現閉包。
- 能夠經過將匿名函數做爲參數或返回值實現閉包。
- 能夠經過use關鍵字引入外部變量,且引入的變量副本。
- 匿名函數均實現了Closure類,且能夠經過Closure::bind()方法將匿名函數綁定到某個類。