"поскольку" по сравнению с “каждым” в Ruby

У меня просто был быстрый вопрос относительно циклов в Ruby. Существует ли различие между этими двумя способами выполнить итерации через набор?

# way 1
@collection.each do |item|
  # do whatever
end

# way 2
for item in @collection
  # do whatever
end

Просто удивление, если это точно то же или если, возможно, существует тонкое различие (возможно, когда @collection ноль).

196
задан the Tin Man 26 August 2014 в 12:37
поделиться

5 ответов

Это единственное различие:

each:

irb> [1,2,3].each { |x| }
  => [1, 2, 3]
irb> x
NameError: undefined local variable or method `x' for main:Object
    from (irb):2
    from :0

for:

irb> for x in [1,2,3]; end
  => [1, 2, 3]
irb> x
  => 3

В цикле for переменная итератора продолжает жить после завершения блока. В цикле each - нет, если только она не была определена как локальная переменная до начала цикла.

В остальном, for - это просто синтаксический сахар для метода each.

Когда @collection становится nil, оба цикла выбрасывают исключение:

Exception: undefined local variable or method `@collection' for main: Object

306
ответ дан 23 November 2019 в 05:18
поделиться

Ваш первый пример,

@collection.each do |item|
  # do whatever
end

более идиоматичен. Хотя Ruby поддерживает такие конструкции циклов, как for и while, синтаксис блоков обычно предпочтительнее.

Еще одно тонкое различие заключается в том, что любая переменная, которую вы объявите в цикле for, будет доступна вне цикла, в то время как переменные в блоке итератора являются частными.

29
ответ дан 23 November 2019 в 05:18
поделиться

Похоже, нет никакой разницы, для использует каждый внизу.

$ irb
>> for x in nil
>> puts x
>> end
NoMethodError: undefined method `each' for nil:NilClass
    from (irb):1
>> nil.each {|x| puts x}
NoMethodError: undefined method `each' for nil:NilClass
    from (irb):4

Как говорит Баярд, каждый из них более идиоматичен. Он скрывает от вас больше и не требует специальных языковых функций. Комментарий Телемаха

для .. в .. устанавливает итератор вне области действия цикла, поэтому

for a in [1,2]
  puts a
end

оставляет определенным после завершения цикла. Где, как , каждый - нет. Это еще одна причина в пользу использования каждого , потому что временная переменная живет более короткий период.

2
ответ дан 23 November 2019 в 05:18
поделиться

Насколько я знаю, использование блоков вместо внутриязыковых управляющих структур более идиоматично.

0
ответ дан 23 November 2019 в 05:18
поделиться

См. « The Evils of the For Loop» для хорошего объяснения (есть одно небольшое различие с учетом диапазона переменных).

Использование каждый считается более идиоматическим использованием Ruby.

43
ответ дан 23 November 2019 в 05:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: