Какой тип закрытия у PHP7? - PullRequest
0 голосов
/ 31 мая 2018

Вот код, это простой контейнер.

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, чтобы сделать его наиболее конкретным?Тип - это функция, а точнее функция, которая возвращает кэш.

Ответы [ 2 ]

0 голосов
/ 31 мая 2018

Если вы конкретно хотите заставить кого-то передать анонимную функцию, то это всегда будет экземпляр класса Closure .

Если то, что вы действительно хотите, - это то, что вы можетеиспользовать как функцию ", вы можете использовать вызываемый псевдотип , который принимает как замыкания, так и различные нотации строк и массивов для ссылок на именованные функции и методы.

Вы также можете преобразоватьлюбой вызываемый в экземпляр Closure с использованием Closure :: fromCallable .

К сожалению, вы не можете получить более конкретную информацию;были предложения о том, чтобы указать конкретные подписи для вызываемых объектов или позволить им соответствовать специально созданным определениям интерфейса, но ни одно из них еще не принято.

Однако вам может потребоваться объект, реализующий нормальный интерфейс с одним методом, иЯ считаю, что этот метод может быть магическим методом __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 и некоторыехорошая документация

0 голосов
/ 31 мая 2018

PHP поддерживает несколько синтаксисов для вызываемых объектов: строка, содержащая имя функции, массив объекта и метода, массив класса и метода в случае статических методов, замыкания первого класса и сгенерированные замыкания.

Подсказка типадля всего этого callable.

Если вы хотите использовать только анонимные функции, то есть замыкания первого класса, используйте Closure.Но это ограничило бы те типы вызываемых, которые вы могли бы принять.

На данный момент PHP не поддерживает подсказки аргументов или подсказки типа возврата для формальных вызываемых аргументов: ваш код не может сказать, например, принимать только замыкания, которые принимаютодин строковый параметр и возвращаемое логическое значение.

...