Изменить значение лексической переменной в выражении HHVM/Hack lambda?

Можно ли изменить значение переменной с лексической областью в лямбда-выражении Hack?

function allTrue(Map<string, bool> $map): bool {
    $valid = 1;
    $map->map($a ==> $valid &= $a);
    return $valid === 1;
}

$map = Map{'foo' => true, 'bar' => false };
var_dump(allTrue($map)); // true

Я ожидаю, что возвращаемое значение будет false

2 ответа

Решение

К сожалению, лямбда-выражения Hack не поддерживают это. Однако вы все равно можете использовать синтаксис закрытия PHP 5.3.

function allTrue(Map<string, bool> $map): bool {
    $valid = 1;
    $map->map(function ($a) use (&$valid) {
        $valid &= $a;
    });
    return $valid === 1;
}

$map = Map{'foo' => true, 'bar' => false };
var_dump(allTrue($map)); // false 

Это работает потому, что: объекты типа Closure, созданные с помощью синтаксиса лямбда-выражений, против синтаксиса закрытия PHP 5.3 являются взаимозаменяемыми;

Из документов

Замечания:
В настоящее время существуют некоторые ограничения для лямбда-выражений, над которыми ведется работа или рассматриваются:

Лямбда-выражения не поддерживают захват переменных по ссылке. Если программист хочет захватить переменные по ссылке, он должен использовать синтаксис закрытия PHP 5.3 и поставить "&" перед переменной в списке "use(..)".

Лямбда-выражения не поддерживают возврат по ссылке в настоящее время, но поддержка может быть добавлена ​​в будущем.

С 2019 года можно также использовать Ref чтобы обойти это.

      function allTrue(Map<string, bool> $map): bool {
  $valid = Ref(1);
  $map->map($a ==> $valid->set($a));
  return $valid->get() === 1;
}

$map = Map{'foo' => true, 'bar' => false };
var_dump(allTrue($map));

См. Https://hhvm.com/blog/2019/10/01/deprecating-references.html.

Другие вопросы по тегам