`raise“foo”`和`raise Exception.new(“foo”)“有什么区别?

在技​​术,哲学,概念或其他方面有什么区别?

raise "foo" 

 raise Exception.new("foo") 

从技术上讲,第一个引发一个RuntimeError消息设置为"foo" ,第二个引发一个Exception消息设置为"foo"

实际上,当你想使用前者和你想使用后者时,有一个显着的区别。

简而言之,你可能需要一个RuntimeError而不是一个Exception 。 没有参数的救援块会捕获RuntimeErrors ,但不会捕获Exception 。 所以,如果你在你的代码中引发一个Exception ,这个代码将不会被捕获:

 begin rescue end 

为了赶上Exception你将不得不这样做:

 begin rescue Exception end 

这意味着从某种意义上说, Exception是一个比RuntimeError更糟的错误,因为你必须做更多的工作才能从中恢复。

所以你想要取决于你的项目如何处理错误。 例如,在我们的守护进程中,主循环有一个空白的救援,它将捕获RuntimeErrors ,报告它们,然后继续。 但是在一两种情况下,我们希望守护进程真的死于一个错误,在这种情况下,我们引发一个Exception ,它直接通过我们的“正常的error handling代码”。

再次,如果你正在编写库代码,你可能需要一个RuntimeError ,而不是一个Exception ,因为你的库的用户会感到惊讶,如果它提出了一个空白的rescue块无法赶上的错误,这将需要一些时间明白为什么。

最后,我应该说RuntimeErrorStandardError类的一个子类,实际的规则是虽然你可以raise 任何types的对象,但是空白的rescue在默认情况下只会捕获inheritance自StandardError任何东西。 其他一切都必须具体。

从官方文件:

 raise raise( string ) raise( exception [, string [, array ] ] ) 

没有参数,在$!引发exception 或者引发一个RuntimeError if $! 是零。 使用单个String参数时,会将该string作为消息引发RuntimeError 。 否则,第一个参数应该是Exception类的名称(或者是发送Exception时返回Exception的对象)。 可选的第二个参数设置与exception关联的消息,第三个参数是一个callback信息数组。 例外情况受到begin...end块的救援条款的限制。

 raise "Failed to create socket" raise ArgumentError, "No parameters", caller