【问题标题】:Using return keyword in Ruby block在 Ruby 块中使用 return 关键字
【发布时间】:2014-03-09 20:51:30
【问题描述】:

我注意到如果我在块内使用关键字return,整个方法都会返回。我发现在 ruby​​ 中,您可以选择使用 return 关键字感到困惑 - 就像:“那么这个东西返回的是什么,如果有的话?开发人员是否打算让这个方法返回一些东西?”所以我喜欢在块内使用return,例如:

def my_method
  items = [ 1, 2, 3 ]

  items_times_ten = items.collect { |o|
    #multiple
    #lines
    #of
    #code ...

    return o * 10  # Ruby exits the method at this point.
  }

  return items_times_ten  #This is never reached.
end

我明白为什么我不需要从街区返回,但如果我的街区更复杂,它似乎有助于清晰。我的问题是,为什么 Ruby 会假设我想将控制权返回两个级别?

如果我的假设不正确,请纠正我。我只是想了解以这种方式处理控制的原因。

【问题讨论】:

  • 我认为这个答案可能会有所帮助stackoverflow.com/a/2325712/1856239
  • 我编辑了整个问题。我不知道为什么这最初让我感到惊讶——我来自 C# 背景,如果我从 for 循环中调用 return(这是一件奇怪的事情),该方法将返回!这里的想法相同。我想我只是因为试图解决问题而感到恼火而被赶上了。
  • 由于 JavaScript 和 Ruby 闭包之间可能存在一些相似之处,因此这个问题并非完全不成立。在 C# 匿名委托中调用 return 也会在方法中保持控制......暂时不要敲自己!

标签: ruby


【解决方案1】:

这就是块/Proc 和 lambda/Method 之间的主要区别之一(另一个主要区别是数量)。如果您不希望调用 return 来退出该方法,则可以推断您希望该块在其流控制中是自包含的,并被视为封装方法。

这个描述本质上就是一个 lambda - 一个匿名方法。然而,一个标准的 ruby​​ 块本质上是一个匿名的 Proc,并且不会影响该方法的流控制。

如 cmets 中所述,您可以使用 next 转义块,而无需将控制权从方法中返回。 'May' 因为next 可能只是继续到方法迭代器传递给块的下一项。

与此相关,请参阅http://yehudakatz.com/2012/01/10/javascript-needs-blocks/Differences between Proc and Lambda

【讨论】:

  • 感谢您的解释 - 有道理。
【解决方案2】:

您所看到的行为可以通过 ProcsLambdasreturn 关键字上下文中在 ruby​​ 中的行为方式来解释。

例如,以下为您提供预期的结果:

def my_method
  items = [ 1, 2, 3 ]
  a = ->(o){return o * 10}  # lambda
  items_times_ten = items.collect(&a)
  return items_times_ten  #This is never reached.
end

p my_method # [10, 20, 30] 

基本上,Proc 中的 return 将停止方法并返回提供的值,另一方面,Lambdasreturn 将它们的值传递给方法。

如果您仍想使用Proc,另一种解决方法是使用隐式return。例如:

def my_method
  items = [ 1, 2, 3 ]

  items_times_ten = items.collect { |o|
    o * 10  # Removed the explicit return
  }

  return items_times_ten  #This is never reached.
end

p my_method # [10, 20, 30] 

【讨论】:

  • 对,隐式返回是有意义的解决方案。
【解决方案3】:

如果您将块视为某种嵌套函数或匿名方法,那么您会期望 return 将块引入产生它的迭代器。但是块是不是方法。 return 总是导致封闭方法返回,无论它在块中嵌套的深度如何。

【讨论】:

  • 是的,在这一点上,我感到很沮丧。这一切都说得通。谢谢。
猜你喜欢
  • 2011-08-09
  • 2021-04-04
  • 1970-01-01
  • 2017-09-16
  • 1970-01-01
  • 1970-01-01
  • 2019-02-22
  • 2014-12-24
  • 2016-03-11
相关资源
最近更新 更多