Ruby中的隐式返回值范围

时间:2014-06-20 21:01:18

标签: ruby return-type implicit-declaration

我使用自定义的include?方法来检查显式和隐式返回之间的区别。我理解#each返回迭代的集合,所以我相信我需要将我的真/假隐式返回放在正确的位置,但是当我这样做时,我会收回该集合而我不是确定要修改的内容。

def self.include?(array, search_item)
  array.each do |elem|
    if elem == search_item
      true
    end
  end
end

以下是我正在检查的测试,但我不了解如何正确匹配退货。为什么它们不匹配或我应该如何理解隐含回报的范围?

  result = MethodReturns.include?(numbers_array, 4)
  expect(result).to eq(true)

  result = MethodReturns.include?(numbers_array, 7)
  expect(result).to eq(false)

3 个答案:

答案 0 :(得分:3)

您需要更改为:

def self.include?(array, search_item)
  array.each do |elem|
    if elem == search_item
      return true
    end
  end
  return false
end

原因是因为方法中的最后一个语句是返回值。在你的情况下,如果没有匹配,你永远不会返回false。确保在想要突破时添加return并立即停止方法执行的其余部分。

答案 1 :(得分:2)

执行的LAST语句提供返回值。在each()循环中发生的最后一件事总是循环的结束(除非你以某种方式突破循环,例如return,break):

def do_stuff()
  [1, 2, 3]. each do |num|
    true if num == num
  end
end

p do_stuff

--output:--
[1, 2, 3]

所以你的真值被抛弃,然后每个()的迭代继续,直到each()循环结束,如你所知,当each()循环结束时,它返回左侧。

以下是隐式返回true的方法示例:

def do_stuff()
  [1, 2, 3]. each do |num|
    #blah
  end

  true
end

each()方法仍然返回数组 - 但是each()方法不是在do_stuff()方法中执行的LAST语句。

在您的示例中,可以执行此操作:

def do_stuff(target)
  found = false

  [1, 2, 3]. each do |num|
    found = true if num == target
  end

  found
end


p do_stuff(2)

--output:--
true

但是,该解决方案会浪费资源,因为在找到匹配项后,each()方法会继续遍历数组。例如,如果您的Array中有100万个元素,并且在Array中的索引0处找到匹配,则each()方法将不必要地继续迭代剩余的999,999个元素。另一方面,当找到匹配时显式返回将终止循环。

明确写出return val永远不是一个错误。随着你越来越有经验,你可以放弃返回部分 - 当适当时 - 向你展示你知道红宝石的世界......但是不时地忽略return仍然会让你失望。

答案 2 :(得分:2)

如果在return块中使用显式each - 到达该代码将导致立即返回值(停止迭代)。这是因为块的non local return功能:

  

Ruby的块支持非本地返回,这意味着从中返回   该块的行为与从块的原始块返回的行为相同   上下文。

因此,如果您只使用显式return

,那么您的代码应该可以正常运行
def self.include?(array, search_item)
  array.each do |elem|
    if elem == search_item
      return true
    end
  end
end