У меня есть код, похожий на этот, который я хотел бы улучшить:
// example type
class Stuff
{
public function __construct($name)
{
$this->name = $name;
}
public function getName()
{
return $this->name;
}
}
// generator function
function searchStuff()
{
yield new Stuff('Fou');
yield new Stuff('Barre');
yield new Stuff('Bazze');
}
// code that iterates over the results of the generator
$stuffIterator = searchStuff();
assert($stuffIterator instanceof Iterator);
foreach ($stuffIterator as $stuff) {
/** @var Stuff $stuff */
echo $stuff->getName() . PHP_EOL;
}
Вещь, которую я хотел бы улучшить, - это аннотация в цикле (третья последняя строка), которую я хотел быхотел бы удалить полностью.Причины:
- . В правильных подсказках типов, которые даже применяются языком
- , не должно быть необходимости, это может отражать или не отражать реальность, т. Е. Оно может нарушать изменения кода.
- это ненужная работа, набирать его и, что еще хуже, читать его.
Мой наивный подход состоял в том, чтобы объявить интерфейс итератора, который добавляет правильную аннотацию типа к универсальному Iterator
interface:
interface StuffIterator extends Iterator
{
public function current(): Stuff;
}
У этого недостатка есть то, что я не могу установить это как "жесткую" аннотацию для функции, только как аннотацию строки документа, потому что "Generators may only declare a return type of Generator, Iterator, Traversable, or iterable"
, что плохо, потому что тогда это не 'Принудительный.Кроме того, моя среда IDE не выбирает тип, но это другая проблема.
Другой подход заключался в написании фактического класса итератора, заключающего в себе Generator
, возвращаемый функцией.Проблема в том, что этот класс также должен быть создан, поэтому я должен был бы вызвать $stuffGenerator = new StuffIterator(searchStuff());
или написать другую функцию-обертку, чтобы сделать это, ни то, ни другое не должно быть необходимым.Тем не менее, глупая IDE не принимает подсказку типа (grrrr ...!).
Итак, вот мой вопрос: Какие альтернативы существуют для этого подхода?Я мог бы представить что-то вроде дженериков C ++ или Java, но, увы, я не могу просто переписать рассматриваемое приложение.
Дополнительные примечания:
- Пример кода работает, это не такпроблема, мои проблемы скорее в удобстве обслуживания, удобочитаемости и элегантности.
- Я не могу просто вернуть массив, использование генератора на данном этапе очень важно.Таким образом, любое предложение, основанное на этом подходе, не является решением.
- В настоящее время я использую PHP 7.1, но не исключаю обновления.Я бы посчитал ответ верным, если бы он тоже потребовал обновления.