`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
块无法赶上的错误,这将需要一些时间明白为什么。
最后,我应该说RuntimeError
是StandardError
类的一个子类,实际的规则是虽然你可以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