Ruby Enumerator - Зачем заканчивать с Exception?
-
13-09-2020 - |
Вопрос
Выполнение итерации блока в Ruby достаточно просто - оно завершается чисто и переходит к остальной части кода.
С другой стороны, выполнение итерации с помощью перечислителя немного более запутанно.Если вы вызываете :each без блока, вместо него возвращается перечислитель.:затем next может быть вызван в перечислителе для получения каждого следующего итеративного значения.
И затем странная часть - когда итерация завершена, вместо того, чтобы перечислитель возвращал nil, он выдает исключение:"итерация завершена".В результате он даже не возвращает значения.
Например:
test = [ 'test_value' ]
enumerator = test.each
enumerator.next
>> "test_value"
enumerator.next
>> StopIteration: iteration reached at end
Является ли причина этого просто в том, что перечислитель может возвращать нулевые значения?Ответ приходит мне в голову только тогда, когда я публикую это (поэтому я все равно собираюсь опубликовать его), но, похоже, так и должно быть.
Если это так, является ли это типичным способом решения подобных проблем?Кажется странным использовать Исключение для обработки кода, который, по сути, работает так, как ожидалось.
Решение
Вы правы в том, что причина в том, что nil
может быть возвращено перечислителем как допустимое значение.Чтобы ответить на ваш вопрос о том, является ли это типичным, Python обрабатывает это таким же образом, используя исключение, также вызываемое StopIteration
.
>>> my_list = [1,2,3]
>>> i = iter(my_list)
>>> i.next()
1
>>> i.next()
2
>>> i.next()
3
>>> i.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
Конечно, большую часть времени next
не вызывается напрямую (each
или for
вместо этого используется цикл), так что этот базовый механизм раскрывается не так часто.
Другие советы
Да, Nil все еще является результатом, что отличается от того, чтобы не иметь значение для возврата.Это в основном так же, как пытаться получить доступ к переменной или местоположению в памяти, который там нет.Вот почему вы хотите исключение, а не возвращать ноль.Похоже, вы поняли это: -)