匿名函数的使用

匿名函数,说白了就是“没有名字的函数”,恩废话。给一段代码可能更为直白:

 
 
  1. $foo = function() {
  2. // this is a closure
  3. }

对,这就是匿名函数,没什么特别的,和一般函数结构神似,唯独少了个函数名。而且这个函数可以作为一个值被赋予一个变量或者对象属性。这种特性使得拥有匿名函数的编程语言再设计一些应用时,更为灵活。

匿名函数和普通函数最大的区别是在于,匿名函数可以作为一个具体的“值”赋予给变量或者对象属性,其次,由于匿名函数可以被定义在不同地方,使得他可以有效利用他所在的局域内的变量(或者说上下文中的变量)。下面例子中就是这样一种情况。

 
 
  1. class foo
  2. {
  3. public function exec(Closure $callback)
  4. {
  5. echo $callback();
  6. }
  7. }
  8.  
  9. $name = 'nick';
  10.  
  11. (new foo)->exec(function() use ($name) {
  12. return 'hi, '. $name;
  13. }); // 输出: hi, nick

我们可以看到,匿名函数使用了上下文中的变量$name。而实际上,这个匿名函数是在另一个地方被执行(是在foo类里面被执行的)。这样使得我们不必将变量name的值通过参数传递到类fooexec方法中,而且可以减少在exec方法中不必要的处理逻辑,使得类更容易专注于自己的职责。

匿名函数的作用还有很多,要知道,函数定义的时候是不会执行的,除非被调用。上文中例子其实就是这样,我们可以看到,例子中,对$name变量的处理是在方法exec被调用后才发生,且利用了匿名函数被定义时的上下文中的变量。这种特性,我们可以利用来实现一个控制反转(IoC)容器。

 
 
  1. /**
  2. * 一个简单的IoC容器
  3. */
  4. class Container
  5. {
  6. protected static $bindings;
  7.  
  8. public static function bind($abstract, Closure $concrete)
  9. {
  10. static::$bindings[$abstract] = $concrete;
  11. }
  12.  
  13. public static function make($abstract)
  14. {
  15. return call_user_func(static::$bindings[$abstract]);
  16. }
  17. }
  18.  
  19. /**
  20. * 示例用的 talk 类
  21. */
  22. class talk
  23. {
  24. public function greet($target)
  25. {
  26. echo 'hi, ' . $target->getName();
  27. }
  28. }
  29.  
  30. /**
  31. * 示例用的 A 类
  32. */
  33. class A
  34. {
  35. public function getName()
  36. {
  37. return 'Nick';
  38. }
  39. }
  40.  
  41. /**
  42. * 示例用的 B 类
  43. */
  44. class B
  45. {
  46. public function getName()
  47. {
  48. return 'Amy';
  49. }
  50. }
  51.  
  52. // 以下代码是主要示例代码
  53.  
  54. // 创建一个talk类的实例
  55. $talk = new talk;
  56.  
  57. // 将A类绑定至容器,命名为foo
  58. Container::bind('foo', function() {
  59. return new A;
  60. });
  61.  
  62. // 将B类绑定至容器,命名为bar
  63. Container::bind('bar', function() {
  64. return new B;
  65. });
  66.  
  67. // 通过容器取出实例
  68. $talk->greet(Container::make('foo')); // hi, Nick
  69. $talk->greet(Container::make('bar')); // hi, Amy

上述例子中,只有在通过make方法获取实例的时候,实例才被创建,这样使得我们可以实现容器,我们依照这一特性,还可以更多的实现高级的特性如事件触发等。利用好匿名函数,可以让应用变得更加丰满。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值