루비의 루프에 관한 간단한 질문이 있습니다. 컬렉션을 반복하는 두 가지 방법 사이에 차이점이 있습니까?
# way 1
@collection.each do |item|
# do whatever
end
# way 2
for item in @collection
# do whatever
end
이것들이 정확히 같은지 또는 미묘한 차이가 있는지 궁금합니다 (아마도 @collection
0 일 때 ).
답변
이것이 유일한 차이점입니다.
마다:
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
에 대한:
irb> for x in [1,2,3]; end
=> [1, 2, 3]
irb> x
=> 3
for
루프를 사용하면 블록이 완료된 후에 반복자 변수가 계속 남아 있습니다. each
루프를 사용하면 루프가 시작되기 전에 이미 로컬 변수로 정의되지 않은 한 루프가 아닙니다.
그 외에는 메소드의 for
구문 설탕 일뿐 each
입니다.
때 @collection
입니다 nil
모두 루프는 예외를 throw :
예외 : main : Object에 대한 정의되지 않은 지역 변수 또는 메소드`@collection ‘
답변
답변
첫 번째 예
@collection.each do |item|
# do whatever
end
더 관용적 입니다. Ruby는 for
and 같은 루핑 구문을 지원하지만 while
일반적으로 블록 구문이 선호됩니다.
또 다른 미묘한 차이점은 for
루프 내에서 선언 한 모든 변수는 루프 외부에서 사용할 수있는 반면 반복자 블록 내의 변수 는 사실상 비공개입니다.
답변
하나 더 ..
number = ["one", "two", "three"]
=> ["one", "two", "three"]
loop1 = []
loop2 = []
number.each do |c|
loop1 << Proc.new { puts c }
end
=> ["one", "two", "three"]
for c in number
loop2 << Proc.new { puts c }
end
=> ["one", "two", "three"]
loop1[1].call
two
=> nil
loop2[1].call
three
=> nil
출처 : http://paulphilippov.com/articles/enumerable-each-vs-for-loops-in-ruby
답변
차이가없는 것처럼 보이며 아래를 for
사용합니다 each
.
$ 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
Bayard가 말했듯이, 각각은 관용적입니다. 더 많은 것을 숨기고 특별한 언어 기능이 필요하지 않습니다.
Telemachus의 의견
for .. in ..
반복자를 루프 범위 밖에서 설정하므로
for a in [1,2]
puts a
end
a
루프가 완료된 후 정의 된 잎 . 어디로 each
하지 않습니다. 어떤 사용을 선호하는 또 다른 이유는 each
임시 변수가 짧은 기간을 살고 있기 때문에.
답변
절대 사용하지 for
않으면 거의 추적 할 수없는 버그가 발생할 수 있습니다.
속지 마십시오. 이것은 관용적 코드 나 스타일 문제에 관한 것이 아닙니다. Ruby의 구현 for
에는 심각한 결함이 있으므로 사용해서는 안됩니다.
다음은 for
버그를 소개 하는 예입니다.
class Library
def initialize
@ary = []
end
def method_with_block(&block)
@ary << block
end
def method_that_uses_these_blocks
@ary.map(&:call)
end
end
lib = Library.new
for n in %w{foo bar quz}
lib.method_with_block { n }
end
puts lib.method_that_uses_these_blocks
인쇄물
quz
quz
quz
%w{foo bar quz}.each { |n| ... }
인쇄물 사용
foo
bar
quz
왜?
A의 for
루프 변수는 n
한번에 단지 한 다음 정의는 모든 반복에 대한 용도가 있음을 정의한다. 따라서 각 블록 은 루프가 종료 될 때까지의 n
값을 갖는 블록을 참조합니다 quz
. 곤충!
에서 each
루프 새로운 변수는 n
가변 위의 예를 들어, 각 반복에 대해 정의 된 n
별도의 세 번 정의된다. 따라서 각 블록 n
은 올바른 값 을 가진 별도 를 참조 합니다.
답변
내가 아는 한, 언어 제어 구조 대신 블록을 사용하는 것이 관용적입니다.