簡體   English   中英

Ruby for循環陷阱?

[英]Ruby for loop a trap?

在對Ruby循環的討論中,與每個循環相比, Niklas B.最近談到了循環“不引入新范圍”。 我想看一些人們如何看待這個問題的例子。

好吧,我擴展了一個問題:在Ruby的其他地方我們看到了什么apears做/結束塊分隔符,但實際上里面沒有范圍? 還有什么別的...做...結束?

好的,問題的另一個擴展,是否有辦法用花括號{block}編寫循環?

讓我們通過一個例子說明這一點:

results = []
(1..3).each do |i|
  results << lambda { i }
end
p results.map(&:call)  # => [1,2,3]

很酷,這是預期的。 現在檢查以下內容:

results = []
for i in 1..3
  results << lambda { i }
end
p results.map(&:call)  # => [3,3,3]

嗯,發生了什么事? 相信我,這些類型的錯誤是令人討厭的追蹤。 Python或JS開發人員會知道我的意思:)

僅僅這一點是我避免像瘟疫這樣的循環的原因,盡管有更多有利於這一立場的好論據。 正如Ben指出的那樣,使用Enumerable的正確方法幾乎總是會導致更好的代碼,而不是使用普通的舊的,命令式的for循環或者有趣的Enumerable#each 例如,上面的例子也可以簡潔地寫成

lambdas = 1.upto(3).map { |i| lambda { i } }
p lambdas.map(&:call)

我擴展了一個問題:在Ruby的其他地方我們看到了什么apears做/結束塊分隔符,但實際上里面沒有范圍? 還有什么別的...做...結束?

每個循環結構都可以這樣使用:

while true do
  #...
end

until false do
  # ...
end

另一方面,我們可以在沒有do情況下編寫其中的每一個(這顯然是可取的):

for i in 1..3
end

while true
end

until false
end

問題的另一個擴展是,有一種方法可以用花括號{block}來編寫循環

不,那里沒有。 另請注意,術語“塊”在Ruby中具有特殊含義。

首先,我會解釋為什么你不希望使用for ,然后解釋為什么你可能。

你不希望使用的主要原因for是它的非習慣。 如果您使用each ,您可以輕松地將each替換為mapfindeach_with_index而無需對代碼進行重大更改。 但是沒有for_mapfor_findfor_with_index

另一個原因是,如果你在each塊中的塊內創建一個變量,並且它之前沒有創建過,那么只要該循環存在,它就會保持存在。 一旦你沒有使用它們就擺脫變量是一件好事。

現在我會提到你可能想要使用for each循環each創建一個閉包,如果重復該循環次數過多,那么該循環可能會導致性能問題。 https://stackoverflow.com/a/10325493/38765中 ,我發布了使用while循環而不是塊使其變慢。

RUN_COUNT = 10_000_000
FIRST_STRING = "Woooooha"
SECOND_STRING = "Woooooha"

def times_double_equal_sign
  RUN_COUNT.times do |i|
    FIRST_STRING == SECOND_STRING
  end
end

def loop_double_equal_sign
  i = 0
  while i < RUN_COUNT
    FIRST_STRING == SECOND_STRING
    i += 1
  end
end

times_double_equal_sign始終持續2.4秒,而loop_double_equal_sign持續0.2至0.3秒。

https://stackoverflow.com/a/6475413/38765中 ,我發現執行空循環需要1.9秒,而執行空塊需要5.7秒。

知道你為什么會不希望使用for ,知道你為什么會想用for ,只有當你需要使用后者。 除非你對其他語言懷有懷舊情緒。 :)

好吧,在1.9之前的Ruby中,偶數塊也不完美。 他們並不總是引入新的范圍:

i = 0
results = []
(1..3).each do |i|
  results << lambda { i }
end
i = 5
p results.map(&:call)  # => [5,5,5]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM