0

我正在使用自定义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)
4

3 回答 3

3

您将要更改为:

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

这样做的原因是因为方法中的最后一条语句是返回值。在您的情况下,如果没有匹配项,您永远不会返回 false。确保return在您想要中断时添加并立即停止其余的方法执行。

于 2014-06-20T21:10:55.053 回答
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() 循环结束,并且如您所知,当 each() 循环结束时,它返回左侧。

下面是一个隐式返回 true 的方法示例:

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

  true
end

each() 方法仍然返回数组——但是 each() 方法不是在 do_stuff() 方法中执行的最后一条语句。

在您的示例中,您可以这样做:

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。例如,如果您的 Array 中有 100 万个元素,并且在 Array 的索引 0 处找到匹配项,则 each() 方法将不必要地继续迭代剩余的 999,999 个元素。另一方面,找到匹配项时显式返回将终止循环。

明确地编写return val. 当你变得更有经验时,你可以放弃返回部分——当适当时——向世界展示你对红宝石的了解......然而,偶尔省略return仍然会让你绊倒。

于 2014-06-20T21:06:36.513 回答
2

如果您在块return内使用显式each- 到达该代码将导致立即返回值(停止迭代)。这是因为块的非本地返回特性:

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

因此,如果您只使用显式,您的代码应该可以正常工作return

def self.include?(array, search_item)
  array.each do |elem|
    if elem == search_item
      return true
    end
  end
end
于 2014-06-21T08:16:18.673 回答