Ruby中的return语句有什么作用?

86

使用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
7个回答

126

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存储返回值,但让方法的其余部分执行。迫不及待要使用它。 - thenengah
5
不,恰恰相反:return会立即退出方法。如果您考虑该示例,如果您知道一切都很好,计算错误性将没有用处。我将编辑我的答案以使其更清晰明了。 - Antal Spector-Zabusky
9
你可以在不带参数的情况下使用returnbreak等关键字 - 它们默认会返回nil - Nakilon

42

如果"return"语句是方法中最后一行要执行的内容,那么使用它是不必要的,因为Ruby会自动返回最后一个被评估的表达式。

你甚至不需要最终的"mood"语句,也不需要IF语句中的那些赋值操作。

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

puts write_code(10)

输出:

错误


39
作为一个没有Ruby背景的人,那个输出绝对让人摸不着头脑。 :) - Patrick
return语句可以提前退出程序的执行。它是用于此目的的。 - Joe.wang
1
返回语句有时候可以帮助方法返回 nil 而不是最后一个表达式的值,因此有时你会看到在方法末尾使用没有参数的返回语句。 - garythegoat
1
@garythegoat:或者你可以直接写nil - Karoly Horvath

4
当我遍历列表并且要在列表中的任何成员符合条件时退出函数时,我使用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”更加有用。 - Nakilon

4

虽然Ruby的确很好地提供了不需要显式指定返回语句的特性,但是作为一种编程标准,我们应该尽可能地在必要的时候指定“return”语句。这有助于让那些来自于不同背景的人,比如C++、Java、PHP等学习Ruby的人更容易阅读代码。“return”语句不会对任何事情造成损害,那么为什么要放弃传统和更标准的函数返回方式呢。


4
“所以为什么要跳过常规和更标准的函数返回方式?” ← 因为在 Ruby 中,省略 return 就是惯例和标准。如果你在格式良好的 Ruby 代码中看到 return,那它应该是有原因存在的,比如提前退出。试图将一个语言的代码风格规范应用到另一个语言上只会让有经验的程序员更难入门,并且难以保持代码风格的一致性。 - David Moles
我仍然会发现自己在行尾加上分号。 - gdbj
这不是 Ruby 之禅中的第二条吗,"隐式优于显式"?;-) - Mark

4

Ruby 永远是最好的选择!最佳方式是:

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

这意味着如果错误数量 > 1,则返回“ERROR”,否则就没有问题。


2

对于来自其他语言的人,有一个小小的警告。比如说你有一个像 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

-1

return在函数的最后一行是Ruby语言中的一种语法糖,并不是必须的。而在大多数过程式编程语言中,你需要在每个(非C++中的void)函数中写上return


4
我不会称其为"语法糖"......这里的核心特点是几乎所有东西都是表达式if语句,语句块。这就是使其具有表现力的原因。 - Karoly Horvath
我同意Karoly的观点——这不是语法糖,因为一切都是表达式。 - fatuhoku

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接