php 5.3新增的閉包語法介紹function() use() {}

  1. <?php  
  2. /** 
  3.  * author: selfimpr 
  4.  * mail: lgg860911@yahoo.com.cn 
  5.  * blog: http://blog.csdn.NET/lgg201 
  6.  * 下面提到的代碼在PHP5.3以上版本運行經過. 
  7.  */  
  8. function callback($callback) {  
  9.     $callback();  
  10. }  
  11. //輸出: This is a anonymous function.<br />/n  
  12. //這裏是直接定義一個匿名函數進行傳遞, 在以往的版本中, 這是不可用的.  
  13. //如今, 這種語法很是舒服, 和JavaScript語法基本一致, 之因此說基本呢, 須要繼續向下看  
  14. //結論: 一個舒服的語法必然會受歡迎的.  
  15. callback(function() {  
  16.     print "This is a anonymous function.<br />/n";  
  17. });  
  18. //輸出: This is a closure use string value, msg is: Hello, everyone.<br />/n  
  19. //這裏首先定義了一個閉包, 此次戶口本上有名字了...  
  20. //use, 一個新鮮的傢伙...  
  21. //衆所周知, 閉包: 內部函數使用了外部函數中定義的變量.  
  22. //在PHP新開放的閉包語法中, 咱們就是用use來使用閉包外部定義的變量的.  
  23. //這裏咱們使用了外部變量$msg, 定義完以後, 又對其值進行了改變, 閉包被執行後輸出的是原始值  
  24. //結論: 以傳值方式傳遞的基礎類型參數, 閉包use的值在閉包建立是就肯定了.  
  25. $msg = "Hello, everyone";  
  26. $callback = function () use ($msg) {  
  27.     print "This is a closure use string value, msg is: $msg. <br />/n";  
  28. };  
  29. $msg = "Hello, everybody";  
  30. callback($callback);  
  31. //輸出: This is a closure use string value lazy bind, msg is: Hello, everybody.<br />/n  
  32. //換一種引用方式, 咱們使用引用的方式來use  
  33. //能夠發現此次輸出是閉包定義後的值...  
  34. //這個其實不難理解, 咱們以引用方式use, 那閉包use的是$msg這個變量的地址  
  35. //當後面對$msg這個地址上的值進行了改變以後, 閉包內再輸出這個地址的值時, 天然改變了.  
  36. $msg = "Hello, everyone";  
  37. $callback = function () use (&$msg) {  
  38.     print "This is a closure use string value lazy bind, msg is: $msg. <br />/n";  
  39. };  
  40. $msg = "Hello, everybody";  
  41. callback($callback);  
  42. //輸出: This is a closure use object, msg is: Hello, everyone.<br />/n  
  43. //閉包中輸出的是以前被拷貝的值爲Hello, everyone的對象, 後面是對$obj這個名字的一個從新賦值.  
  44. //能夠這樣考慮  
  45. //1. obj是對象Hello, everyone的名字  
  46. //2. 對象Hello, everyone被閉包use, 閉包產生了一個對Hello, everyone對象的引用  
  47. //3. obj被修改成Hello, everybody這個對象的名字  
  48. //4. 注意, 是名字obj表明的實體變了, 而不是Hello, everyone對象, 那天然閉包的輸出仍是前面的Hello, everyone  
  49. $obj = (object) "Hello, everyone";  
  50. $callback = function () use ($obj) {  
  51.     print "This is a closure use object, msg is: {$obj->scalar}. <br />/n";  
  52. };  
  53. $obj = (object) "Hello, everybody";  
  54. callback($callback);  
  55. //輸出: This is a closure use object, msg is: Hello, everybody.<br />/n  
  56. //仍是按照上面的步驟, 循序漸進的來吧:  
  57. //1. obj名字指向Hello, everyone對象  
  58. //2. 閉包產生一個引用指向Hello, everyone對象  
  59. //3. 修改obj名字指向的對象(即Hello, everyone對象)的scalar值  
  60. //4. 執行閉包, 輸出的天然是Hello, everybody, 由於其實只有一個真正的對象  
  61. $obj = (object) "Hello, everyone";  
  62. $callback = function () use ($obj) {  
  63.     print "This is a closure use object, msg is: {$obj->scalar}. <br />/n";  
  64. };  
  65. $obj->scalar = "Hello, everybody";  
  66. callback($callback);  
  67. //輸出: This is a closure use object lazy bind, msg is: Hello, everybody.<br />/n  
  68. //閉包引用的是什麼呢? &$obj, 閉包產生的引用指向$obj這個名字所指向的地址.  
  69. //所以, 不管obj怎麼變化, 都是逃不脫的....  
  70. //因此, 輸出的就是改變後的值  
  71. $obj = (object) "Hello, everyone";  
  72. $callback = function () use (&$obj) {  
  73.     print "This is a closure use object lazy bind, msg is: {$obj->scalar}. <br />/n";  
  74. };  
  75. $obj = (object) "Hello, everybody";  
  76. callback($callback);  
  77. /** 
  78.  * 一個利用閉包的計數器產生器 
  79.  * 這裏其實借鑑的是Python中介紹閉包時的例子... 
  80.  * 咱們能夠這樣考慮: 
  81.  *      1. counter函數每次調用, 建立一個局部變量$counter, 初始化爲1. 
  82.  *      2. 而後建立一個閉包, 閉包產生了對局部變量$counter的引用. 
  83.  *      3. 函數counter返回建立的閉包, 並銷燬局部變量, 但此時有閉包對$counter的引用,  
  84.  *          它並不會被回收, 所以, 咱們能夠這樣理解, 被函數counter返回的閉包, 攜帶了一個遊離態的 
  85.  *          變量. 
  86.  *      4. 因爲每次調用counter都會建立獨立的$counter和閉包, 所以返回的閉包相互之間是獨立的. 
  87.  *      5. 執行被返回的閉包, 對其攜帶的遊離態變量自增並返回, 獲得的就是一個計數器. 
  88.  * 結論: 此函數能夠用來生成相互獨立的計數器. 
  89.  */  
  90. function counter() {  
  91.     $counter = 1;  
  92.     return function() use(&$counter) {return $counter ++;};  
  93. }  
  94. $counter1 = counter();  
  95. $counter2 = counter();  
  96. echo "counter1: " . $counter1() . "<br />/n";  
  97. echo "counter1: " . $counter1() . "<br />/n";  
  98. echo "counter1: " . $counter1() . "<br />/n";  
  99. echo "counter1: " . $counter1() . "<br />/n";  
  100. echo "counter2: " . $counter2() . "<br />/n";  
  101. echo "counter2: " . $counter2() . "<br />/n";  
  102. echo "counter2: " . $counter2() . "<br />/n";  
  103. echo "counter2: " . $counter2() . "<br />/n";  
  104. ?>  
相關文章
相關標籤/搜索