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

來源:互聯網
上載者:User

標籤:ever   類型   var   anon   sdn   csdn   函數   修改   target   

  1. <?php  
  2. /** 
  3.  * author: selfimpr 
  4.  * mail: [email protected] 
  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. ?>  

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

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.