Ruby 的返回点是啥?

Posted

技术标签:

【中文标题】Ruby 的返回点是啥?【英文标题】:what is the point of return in Ruby?Ruby 的返回点是什么? 【发布时间】:2011-06-03 20:14:08 【问题描述】:

return 和只放一个如下变量有什么区别:

不返回

def write_code(number_of_errors)
  if number_of_errors > 1
     mood = "Ask me later"
  else
     mood = "No Problem"
  end  
  mood
end

返回

def write_code(number_of_errors)
  if number_of_errors > 1
    mood =  "Ask me later"
  else
    mood = puts "No Problem"
  end  
  return mood
end

【问题讨论】:

【参考方案1】:

对于那些来自其他语言的人的一个小警告。假设您有一个类似 OP 的函数,并且您利用“最后计算的”规则自动设置您的返回值:

def write_code(number_of_errors)
  if number_of_errors > 1
     mood = "Ask me later"
  else
     mood = "No Problem"
  end  
end

假设您添加了一个调试(或日志记录)语句:

def write_code(number_of_errors)
  if number_of_errors > 1
     mood = "Ask me later"
  else
     mood = "No Problem"
  end  
  puts "### mood = #mood"
end

现在猜猜是什么。你已经破坏了你的代码,因为 puts 返回 nil,它现在成为函数的返回值。

解决方案是养成始终明确地将返回值放在最后一行的习惯,就像 OP 所做的那样:

def write_code(number_of_errors)
  if number_of_errors > 1
     mood = "Ask me later"
  else
     mood = "No Problem"
  end  
  puts "### mood = #mood"
  mood
end

【讨论】:

【参考方案2】:

Ruby 总是返回!最好的办法是

def write_code(number_of_errors)
  (number_of_errors > 1)? "ERROR" : "No Problem"
end

这意味着如果 number_of_errors > 1 它将返回 ERROR 否则没有问题

【讨论】:

【参考方案3】:

如果“return”是方法中要执行的最后一行,则不需要使用“return”,因为 Ruby 会自动返回最后计算的表达式。

你甚至不需要最后的“情绪”,也不需要在 IF 语句中进行那些赋值。

def write_code(number_of_errors)
    if number_of_errors > 1
       "ERROR"
    else
       "No Problem"
    end  
end

puts write_code(10)

输出:

错误

【讨论】:

来自非 Ruby 背景,该输出绝对是 WTF。 :) return 可以提前退出执行。这是工作。 Return 也有助于让方法返回 nil 而不是最后评估的表达式,因此有时您会在方法末尾看到没有参数的返回。 @garythegoat: 或者你可以直接写nil【参考方案4】:

return让你早日爆发:

def write_code(number_of_errors)
  return "No problem" if number_of_errors == 0
  badness = compute_badness(number_of_errors)
  "WHAT?!  Badness = #badness."
end

如果number_of_errors == 0,则"No problem" 将立即返回。但是,正如您所观察到的,在方法结束时,它是不必要的。


编辑:为了证明return 立即退出,考虑这个函数:

def last_name(name)
  return nil unless name
  name.split(/\s+/)[-1]
end

如果您将此函数称为last_name("Antal S-Z"),它将返回"S-Z"。如果将其称为last_name(nil),则返回nil。如果return 没有立即中止,它会尝试执行nil.split(/\s+/)[-1],这会引发错误。

【讨论】:

好的,很好的例子。所以 return 存储返回值,但让方法的其余部分执行。迫不及待想使用它。 不,反过来:return 立即 退出该方法。如果您考虑该示例,如果您知道一切正常,则计算不良程度将没有用。我将编辑我的答案以使其更清楚。 您可以使用returnbreak 等不带参数 - 默认情况下它们会返回nil【参考方案5】:

它漂亮的 ruby​​ 提供了不明确指定 return 语句的好特性,但我只是觉得,作为一种编程标准,应该始终努力在需要的地方指定“return”语句。这有助于使来自不同背景(如 C++、Java、php 等)和学习 ruby​​ 的人的代码更具可读性。 “return” 语句不会造成任何损害,所以为什么要跳过传统和更标准的从函数返回的方式。

【讨论】:

"那么为什么要跳过从函数返回的传统和更标准的方式" ← 因为 在 Ruby 中,省略 return 传统标准。如果您在样式良好的 Ruby 代码中看到 return,那么它应该存在是有原因的,例如 breaking out early。尝试将代码样式约定从一种语言应用到另一种语言只会让有经验的程序员更难入职并保持自己的代码样式一致。 我仍然发现自己在行尾加上分号 这不是 Ruby 禅宗中的#2,“隐式优于显式”吗? ;-)【参考方案6】:

我在浏览列表时使用 return,如果列表中的任何成员符合条件,我想退出该函数。我可以用一个语句来完成这个,比如:

list.select|k| k.meets_criteria.length == 0

在某些情况下,但是

list.each|k| return false if k.meets_criteria

也是一条线——在我看来,增加了一些灵活性。例如,第一个示例假定这是方法中的唯一行,并且无论如何我们都希望从这一点返回。但如果这是一个测试,看看是否可以安全地继续该方法的其余部分,第一个示例将需要以不同的方式处理它。

编辑:

要增加一些灵活性,请考虑以下代码行:

list_of_method_names_as_symbols.each|k| list_of_objects.each|j| return k if j.send(k)

我确信这可以在一行中完成,无需return,但我不知道该怎么做。

但现在这是一个相当灵活的代码行,可以使用任何布尔方法列表和实现这些方法的对象列表来调用。

编辑

需要注意的是,我假设这一行是在一个方法中,而不是在一个块中。


但这主要是一种风格选择,我认为在大多数情况下,您可以并且可能应该避免使用return

【讨论】:

break 在这些情况下更加有用。【参考方案7】:

函数最后一行return 的不必要性只是Ruby 的语法糖。在大多数过程语言中,您需要在每个(C++ 中非 void)函数中编写 return

【讨论】:

我不会称它为句法糖...这里的核心特征是几乎所有东西都是一个表达式if 语句,语句块。这就是允许这种表现力的原因。 我同意 Karoly 的观点——它不是语法糖,因为一切都是表达式。

以上是关于Ruby 的返回点是啥?的主要内容,如果未能解决你的问题,请参考以下文章

关于VC++的Winmain函数(WINAPI是啥?)

||= 在 Ruby 中是啥意思? [复制]

||= 在 Ruby 语言中是啥意思? [复制]

Ruby 中 GraphQL 类型的字段定义中感叹号的目的是啥?

ruby中proc和lambda的return区别

在 Ruby on Rails 中测试模型实例是不是为“空”的最佳方法是啥?