У меня просто был быстрый вопрос по поводу циклов в Ruby. Есть ли разница между этими двумя способами перебора коллекции?
# way 1
@collection.each do |item|
# do whatever
end
# way 2
for item in @collection
# do whatever
end
Просто интересно, если они точно такие же, или, может быть, есть небольшая разница (возможно, когда @collection
ноль).
x
остается сценарий for, связана с тем, что (вообще говоря) ключевые слова не создают новых областей действия. Если , если , не начать , для , в то время и т. д. все работают с текущей областью.#each
однако принимает блок. Блоки всегда добавляют свою собственную область поверх текущей области. Это означает, что объявление новой переменной в блоке (следовательно, новой области видимости) не будет доступно извне блока, поскольку эта дополнительная область там недоступна.См. « Пороки For Loop » для хорошего объяснения (есть одно небольшое различие, учитывая переменную область видимости).
Использование
each
в считаются более идиоматическим использованием Ruby.источник
Ваш первый пример,
более идиоматичный . Хотя Ruby поддерживает циклические конструкции, такие как
for
иwhile
, обычно предпочтителен блочный синтаксис.Другое тонкое отличие состоит в том, что любая переменная, которую вы объявляете в
for
цикле, будет доступна вне цикла, тогда как переменные в блоке итератора фактически являются закрытыми.источник
while
и наuntil
самом деле есть некоторые очень конкретные применения, которые не могут быть заменены каждым, например, для генерации уникальных значений или для REPL.Еще один другой ..
источник: http://paulphilippov.com/articles/enumerable-each-vs-for-loops-in-ruby
для более понятного: http://www.ruby-forum.com/topic/179264#784884
источник
Похоже, что нет никакой разницы,
for
используетeach
внизу.Как говорит Баярд, каждый более идиоматичен. Он скрывает от вас больше и не требует специальных языковых функций. Комментарий Телемаха
for .. in ..
устанавливает итератор за пределы цикла, поэтомулистья
a
определены после завершения цикла. Где какeach
нет. Что является еще одной причиной в пользу использованияeach
, потому что временная переменная живет более короткий период.источник
for
не использоватьeach
под. Смотрите другие ответы.Никогда не используйте
for
его, это может привести к почти неразличимым ошибкам.Не обманывайте себя, речь идет не о идиоматических проблемах с кодом или стилем. Реализация Ruby
for
имеет серьезный недостаток и не должна использоваться.Вот пример, где
for
вводится ошибка,Печать
Использование
%w{foo bar quz}.each { |n| ... }
отпечатковЗачем?
В
for
цикле переменнаяn
определяется один и только раз, а затем это одно определение используется для всех итераций. Следовательно, каждый блок ссылается на один и тот же,n
который имеет значениеquz
к моменту окончания цикла. Ошибка!В
each
цикле новая переменнаяn
определяется для каждой итерации, например, выше, переменнаяn
определяется три раза. Следовательно, каждый блок относится к отдельномуn
с правильными значениями.источник
Насколько я знаю, использование блоков вместо структур управления на языке более идиоматично.
источник
Я просто хочу особо отметить цикл for in в Ruby. Может показаться, что эта конструкция похожа на другие языки, но на самом деле это выражение, похожее на любую другую циклическую конструкцию в Ruby. Фактически, for работает с объектами Enumerable так же, как и каждый итератор.
Коллекция, передаваемая для in, может быть любым объектом, у которого есть метод каждого итератора. Массивы и хэши определяют каждый метод, также как и многие другие объекты Ruby. Цикл for / in вызывает каждый метод указанного объекта. Поскольку этот итератор выдает значения, цикл for присваивает каждое значение (или каждый набор значений) указанной переменной (или переменным) и затем выполняет код в теле.
Это глупый пример, но он иллюстрирует тот факт, что цикл for in работает с ЛЮБЫМ объектом, который имеет каждый метод, так же, как и каждый итератор:
А теперь каждый итератор:
Как вы можете видеть, оба отвечают на каждый метод, который возвращает значения обратно в блок. Как все здесь заявили, определенно предпочтительнее использовать каждый итератор, чем цикл in. Я просто хотел показать, что в цикле for нет ничего волшебного. Это выражение, которое вызывает каждый метод коллекции, а затем передает его в свой блок кода. Следовательно, это очень редкий случай, который вам нужно использовать для in. Используйте каждый итератор почти всегда (с дополнительным преимуществом области видимости блока).
источник
В цикле «for» локальная переменная все еще живет после каждого цикла. В «каждом» цикле локальная переменная обновляется после каждого цикла.
источник