【问题标题】:Implicit return value scope in RubyRuby 中的隐式返回值范围
【发布时间】:2014-08-11 16:50:25
【问题描述】:

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

【问题讨论】:

    标签: ruby return-type implicit-declaration


    【解决方案1】:

    您将要更改为:

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

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

    【讨论】:

    • 您的代码是正确的,但您的解释不正确。 return inside 循环至关重要,否则 true 将被 each 吞并并且永远不会被返回。
    • 我总是在需要基本突破执行方法时写return,所以我从来没有想过这个。感谢您的补充。
    • @Max 进一步说明:块返回的值是块中执行的最后一个表达式。 each 方法接受一个块,在这种情况下,如果当前元素是搜索项,则该块确实返回 true,否则返回 false。但是,这个问题是,each 方法忽略了块的每次执行的输出,而是定义为返回调用每个方法的数组。因此,由于 each 方法调用是该方法中的最后一个表达式,因此此包含的实现返回数组?
    【解决方案2】:

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

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

    明确写成return val 绝不是错误的。随着您的经验越来越丰富,您可以放弃返回部分——在适当的时候——向世界展示您了解 ruby​​...但是时不时地省略 return 仍然会让您感到困惑。

    【讨论】:

      【解决方案3】:

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

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

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

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

      【讨论】:

        猜你喜欢
        • 2010-11-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多