我的代码应该在数组中打印整数。
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)
当我删除返回时,代码完全按照需要工作。
为了找出我对积木理解的错误,我会阅读相关的帖子post1和post2。但是,我无法弄清楚调用方法和块的确切方式以及为什么我的方法不正确。
是否有一些调用堆栈图解释?任何简单的解释? 我很困惑,因为我之前只用Java编程。
答案 0 :(得分:1)
您通常不需要确切地担心使用哪些块。
在这种情况下,return
将从外部范围返回,例如如果这些行是在一个方法中,那么从该方法。它就像在Java中的循环中放置return
语句一样。
其他提示:
select
用于创建复制数组,其中只选择满足块内条件的元素:
only_ints = odds_n_ends.select { |x| x.is_a?(Integer) }
您正在使用它作为循环播放&#34;传回&#34;整数变量,在这种情况下你会这样做:
only_ints = []
odds_n_ends.each { |x| if x.is_a?(Integer) then only_ints << x end }
答案 1 :(得分:1)
如果您尝试将代码包装在方法中,那么它不会给您一个错误:
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没有达到那个目标。当你在Proc中放入return时,你将返回整个方法的范围。在你的例子中,你没有任何放置代码的方法,因此在遇到'return'之后,它不知道在哪里'跳转',在哪里继续。
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
见this link。它基本上表明:
返回枚举中每个元素的数组,其中Pattern === 元件。
要理解Pattern ===元素,只需想象Pattern是一个集合(假设是一组整数)。元素可能是也可能不是该集合的元素(整数)。怎么找出来?使用===。如果你输入Ruby:
puts Integer === 34
它将评估为真。如果你把:
puts Integer === 'hey'
它将评估为假。
希望这有帮助!
答案 2 :(得分:0)
在ruby中,一个方法总是返回它的最后一个语句,所以通常你不需要返回它,除非你想过早地返回。
在您的情况下,您不需要返回任何内容,因为select将创建一个新数组,其中只包含对给定块返回true的元素。因为ruby使用
自动返回它的最后一个语句 { |x| x.is_a?(Integer) }
就足够了。 (另外你想要返回true而不是x,如果你想到&#34;返回选择期望&#34;,但是因为ruby对待不是真的它也有效......)
另一件重要的事情是了解导致问题的proc(&amp; blocks)和lambdas的关键区别:
在Proc中使用return
将返回使用proc的方法。
在Lambda中使用return
将返回它的值,就像方法一样。
将procs视为您在方法中注入的代码片段,将lambda视为匿名方法。
良好且易于理解阅读:Understanding Ruby Blocks, Procs and Lambdas
将块传递给方法时,您只需将要返回的值作为最后一个语句放入,也可以在if-else子句中使用,并且ruby将使用最后实际到达的语句。