簡體   English   中英

了解紅寶石區塊返回的簡單方法

[英]Simple way to understand returning from a block in ruby

我的代碼應該在數組中打印整數。

odds_n_ends = [:weezard, 42, "Trady Blix", 3, true, 19, 12.345]    
ints = odds_n_ends.select { |x| if x.is_a?(Integer) then return x end }
puts ints

它在第二行給我一個錯誤- in 'block in <main>': unexpected return (LocalJumpError)

當我刪除退貨時,代碼將完全按照需要工作。

為了找到理解塊的錯誤,我閱讀了相關的文章post1post2 但是,我無法弄清楚調用方法和塊的確切方式以及為什么我的方法不正確。

為此有一些調用堆棧圖說明嗎? 有什么簡單的解釋嗎? 我很困惑,因為我以前只是用Java編程。

通常,您不必完全擔心要使用哪些塊。

在這種情況下, return將從外部范圍返回,例如,如果這些行在方法中,則從該方法返回。 就像將return語句放在Java循環中一樣。

其他提示:

select用於創建一個復制的數組,其中僅選擇滿足塊內條件的元素:

only_ints = odds_n_ends.select { |x| x.is_a?(Integer) }

您將其用作循環以“傳回”整數變量,在這種情況下,您可以這樣做:

only_ints = []
odds_n_ends.each { |x| if x.is_a?(Integer) then only_ints << x end }

如果您嘗試將代碼包裝在一個方法中,那么它不會給您錯誤:

def some_method
  odds_n_ends = [:weezard, 42, "Trady Blix", 3, true, 19, 12.345]
  ints = odds_n_ends.select { |x| if x.is_a?(Integer) then return true end }
  puts ints
end

puts some_method

此代碼輸出為true。 但是等等,將整數放在哪里??? Ruby沒有做到這一點。 當將return放入Proc中時,您將返回整個方法的范圍。 在您的示例中,您沒有任何用於放置代碼的方法,因此在遇到“返回”之后,它不知道“跳轉到”哪里,繼續到哪里。

Array#select基本上是這樣工作的:對於數組的每個元素(在代碼中用| x |表示),它會評估您剛剛放入的塊,如果該塊的值為true,則該元素將包含在其中。新數組。 嘗試從第二行中刪除“ return”,您的代碼將起作用:

ints = odds_n_ends.select { |x| if x.is_a?(Integer) then true end }

但是,這不是最接近Ruby的方式,您不必告訴Ruby顯式返回true。 塊({}之間的代碼)就像方法一樣,最后一個表達式是方法的返回值。 因此,這將同樣有效:

ints = odds_n_ends.select { |x| if x.is_a?(Integer) } # imagine the code between {} is
#a method, just without name like 'def is_a_integer?' with the value of the last expression
#being returned.

順便說一句,有一種更優雅的方法可以解決您的問題:

odds_n_ends = [:weezard, 42, "Trady Blix", 3, true, 19, 12.345]    
ints = odds_n_ends.grep(Integer)
puts ints

看到這個鏈接 它基本上指出:

返回枚舉中每個包含Pattern ===元素的元素的數組。

要了解Pattern ===元素,只需想象一下Pattern是一個集合(比如說一組Integer)。 元素可能是或可能不是該集合(整數)的元素。 如何找出? 使用===。 如果輸入Ruby:

puts Integer === 34

它將評估為真實。 如果您輸入:

puts Integer === 'hey'

它將評估為假。

希望這對您有所幫助!

在ruby中,方法總是返回其最后一條語句,因此一般而言,除非您想過早返回,否則無需返回。

在您的情況下,您無需返回任何內容,因為select將創建一個新數組,其中僅包含對於給定塊返回true的元素。 由於ruby自動返回它的最后一條語句,使用

{ |x| x.is_a?(Integer) }

就足夠了。 (另外,如果您考慮“返回select期望的內容”,則希望返回true而不是x,但是因為ruby不會將nil視為true,所以它也可以工作...)

重要的另一件事是要了解導致您出現問題的proc(&塊)和lambda的關鍵區別:

在Proc中使用return將返回使用proc的方法。

在Lambda中使用return將像方法一樣返回其值。

將procs視為您在方法中注入的代碼段,而將lambda視為匿名方法。

容易理解的好書: 了解Ruby塊,Procs和Lambdas

當將塊傳遞給方法時,您只需將要返回的值放在最后一條語句中,該值也可以放在if-else子句中,並且ruby將使用最后實際到達的語句。

暫無
暫無

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

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