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