Поэтому я переписал это, чтобы, надеюсь, было яснее о том, что я пытаюсь сделать. Во время некоторого анализа данных получаются некоторые значения, связанные с некоторыми кодами. Намерение состоит в том, чтобы захватить конкретное значение someCode, имеющее самый низкий приоритет, независимо от порядка, который получили someCode / someValue (s). Проблема, препятствующая тому, чтобы это работало, заключается в том, что замыкание создается каждый раз, когда вызывается частная функция, и поэтому значение $ priordenceOfCodeCaptured всегда сбрасывается в ноль. Если бы я мог держать закрытие вокруг, тогда все могло бы работать как задумано.
private function Foo($particularValue, $someValue, $someCode) {
switch ($someCode) {
case:
CODE1:
case:
CODE2:
$c = function () use ($someCode, $someValue) {
static $precedenceOfCodeCaptured = null;
$precedenceArray = array(
CODE2 => 1,
CODE1 => 2
);
if ((is_null($someValue))) {//first time the case statement matched because $someValue==null
$precedenceOfCodeCaptured = $precedenceArray[$someCode];
$particularValue = someValue;
} else if ($precedenceArray[$someCode] <= $precedenceOfCodeCaptured) {
$particularValue = someValue;
}
};
$c();
break;
...
}
}//end of private method
Каждый раз, когда вызывается Foo, вы создаете новую функцию / замыкание, поскольку вы оцениваете функцию (), и именно это делает оценочная функция ()!
Если вы хотите, чтобы Foo () возвращала одну и ту же функцию / замыкание каждый раз, оцените ее только один раз. Возможно, используйте одноэлементный шаблон, в котором вы проверите, была ли инициализирована некоторая переменная более высокого уровня, содержащая функцию, и инициализируете ее, если нет.
Например:
$c = null;
private function Foo(){
if ($c == null) {
$c = function() use ( $whatever){
static $x = 0;
echo "x= $x";
$x++;
...
};
}
$ С ();
} // конец частного метода
(но, пожалуйста, не используйте глобальные переменные в вашем реальном коде!)
Попробуй это:
static $x = 0;
private function Foo() {
$c = function() use ( $whatever){
echo "x= $x";
self::$x++;
...
};
$c();
}
<?php
class example{
private function foo(){
static $_closure;
if( ! $_closure ){
$_closure = function(){
static $_state;
/* . . . */
};
}
$_closure();
}
}
Обратите внимание, что замыкание является статическим (оно создается при первом использовании, а не снова), как и переменная, которая хранит состояние внутри замыкания.
Однако, как указано в других ответах, в лучшем случае это «бессмысленно». $_closure
должен быть другим методом класса; $_state
должен быть свойством класса (в замыкании не требуется ничего статического, в foo()
ни в классе). Подобное закрытие не является «более чистым», более читабельным или производительным (на самом деле, скорее всего, обратное).
Это может иметь смысл, если вы делаете что-то вроде:
… но в нынешнем виде это просто неправильный подход. Инструменты для этого уже существуют.