Если вы специально хотите заставить кого-то передать анонимную функцию, то это всегда будет экземпляр класс замыкания.
Если на самом деле вам нужно «что-то, что вы можете использовать как функцию», вы можете использовать вызываемый псевдотип, который принимает как замыкания, так и различные нотации строк и массивов для ссылок на именованные функции и методы.
Вы также можете преобразовать любой callable в экземпляр 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
и хорошую документацию.
person
IMSoP
schedule
30.05.2018
get_class
и введите намек на то, что он возвращает...? - person ficuscr   schedule 31.05.2018use
. Переменные, импортированные с помощьюuse
, действуют точно так же, как вы ожидаете от закрытия, и могут быть захвачены по значению или ссылке по усмотрению пользователя. - person IMSoP   schedule 31.05.2018