繁体   English   中英

什么是PHP7类型的闭包?

[英]What is the PHP7 type of a closure?

这是代码,它是一个简单的容器。

class Application
{
  private $recipes;
  private $instances;

  public function configureCache(XXXXXXXX $closure) {
    $recipes['cache'] = $closure;
  }

  public function getCache(): Cache {
    if (empty($instances['cache'])) {
      $instances['cache'] = $recipes['cache']();
    }
    return $instances['cache'];
  }
}

此代码在PHP 7.1+上运行。 我可以为XXXXXXXX填写哪些内容以使其最具体? 类型是一个函数,更具体地说是一个返回Cache的函数。

PHP支持可调用实体的几种语法:包含函数名称的字符串,对象和方法的数组,静态方法的类和方法数组,第一类闭包和生成的闭包。

所有这些的类型提示都是callable

如果只想要匿名函数,即第一类闭包,请使用Closure 但这会限制你可以接受的可赎回种类。

截至目前,PHP不支持关于正式可调参数的参数提示或返回类型提示:例如,您的代码不能说只接受带有一个字符串参数并返回布尔值的闭包。

如果您特别想强制某人传递匿名函数,那么它将始终是Closure类的一个实例。

如果你真正想要的是“你可以像函数一样使用的东西”,你可以使用callable伪类型 ,它接受闭包和各种字符串和数组符号来引用命名函数和方法。

您还可以使用Closure :: fromCallable将任何可调用对象转换为Closure实例。

不幸的是,你不能得到更具体的东西; 有提议暗示特定的callables签名,或允许他们满足特制的接口定义,但尚未采用任何。

但是,你可以要求一个对象用一个方法实现一个普通的接口,我相信这个方法可能是神奇的__invoke方法 然后调用者可以使用匿名类而不是匿名函数:

interface CacheFactory {
    public function __invoke(): Cache;
} 
$app->configureCache(new class implements CacheFactory {
    public function __invoke(): Cache {
          return new Cache;
    }
});

请注意,生成的对象本身将传递callable类型提示以及CacheFactory ,并且可以像示例中的匿名函数一样使用。

但是,即使使用此解决方案,也只在运行时检查类型,因此此代码本身不会引发任何错误,并且在实际运行回调时,您只会收到10%的类型错误:

$app->configureCache(new class implements CacheFactory {
    public function __invoke(): Cache {
          return rand(0,10) > 9 ? "Nonsense" : new Cache;
    }
});

大多数情况下,您可能只想要callable和一些好的文档。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM