Làm thế nào tôi có thể trả lại một cái gì đó sớm từ một khối?


90

Nếu tôi muốn làm điều gì đó như thế này:

collection.each do |i|
   return nil if i == 3

   ..many lines of code here..
end

Làm thế nào tôi sẽ có được hiệu ứng đó? Tôi biết tôi có thể chỉ gói mọi thứ bên trong khối trong một câu lệnh if lớn, nhưng tôi muốn tránh việc lồng vào nhau nếu có thể.

Break sẽ không hoạt động ở đây, bởi vì tôi không muốn dừng lặp lại các phần tử còn lại.

Câu trả lời:


176

nextbên trong một khối trả về từ khối. breakbên trong một khối trả về từ hàm đã nhường cho khối. Đối với eachđiều này có nghĩa là breakthoát khỏi vòng lặp và nextchuyển sang lần lặp tiếp theo của vòng lặp (do đó là tên). Bạn có thể trả về các giá trị với next valuebreak value.


53
+1 cho next valuebreak value. Chính xác những gì tôi đang tìm kiếm.
Joshua Pinter,

1
break valuekhông hiệu quả với tôi, trong khi vẫn next valuehoạt động tốt. Cảm ơn rất nhiều.
Francesco Belladonna

4
Tôi không chắc định nghĩa của bạn về next và break là đúng. Ít nhất, họ đang khó hiểu. break thoát khỏi vòng lặp trong cùng, tiếp theo chuyển bạn đến lần lặp tiếp theo. source: tutorialspoint.com/ruby/ruby_loops.htm
WattsInABox

3
@WattsInABox nextbreakkhông có cách nào cụ thể cho các cấu trúc lặp, vì vậy bài viết bạn đã liên kết rất dễ gây hiểu lầm (vì nó có hàm ý ngược lại). Và các mô tả của tôi chắc chắn là chính xác khi nextbreakđược sử dụng bên trong các khối (lưu ý rằng whileforhiếm khi, nếu có, được sử dụng trong Ruby nên 99% việc sử dụng nextbreaknằm trong các khối).
sepp2k

Tôi nghĩ bạn có nghĩa là khối không lặp lại. Đó là những gì khó hiểu về nó. Ngoài ra, tôi không đồng ý với khẳng định 99% của bạn, nhưng đó là một lập luận khác.
WattsInABox

11
#!/usr/bin/ruby

collection = [1, 2, 3, 4, 5 ]

stopped_at = collection.each do |i|
   break i if i == 3

   puts "Processed #{i}"
end

puts "Stopped at and did not process #{stopped_at}"

5

Trong trường hợp này, bạn có thể sử dụng break để kết thúc sớm vòng lặp:

collection.each do |i|
  break if i == 3
  ...many lines
end

... tất nhiên, điều này giả sử rằng bạn không thực sự muốn trả về một giá trị, chỉ cần thoát ra khỏi khối.


Điều này sẽ không chỉ trở lại từ khối, nó sẽ trở lại từ mỗi khối. Vì vậy, vòng lặp sẽ kết thúc, không tiếp tục với giá trị tiếp theo. Không chắc rằng đó là những gì dự định.
sepp2k

4
Bạn có thể sử dụng một giá trị breaktrong Ruby - break 5sẽ eachtrả về 5.
Chuck

1
Cảm ơn, nhưng tôi không muốn ngừng lặp lại.
ryeguy
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.