`raise "foo"` 和 `raise Exception.new("foo")` 有啥区别?
Posted
技术标签:
【中文标题】`raise "foo"` 和 `raise Exception.new("foo")` 有啥区别?【英文标题】:What is the difference between `raise "foo"` and `raise Exception.new("foo")`?`raise "foo"` 和 `raise Exception.new("foo")` 有什么区别? 【发布时间】:2011-06-15 14:26:08 【问题描述】:两者之间有什么区别——技术、哲学、概念或其他方面
raise "foo"
和
raise Exception.new("foo")
?
【问题讨论】:
【参考方案1】:From the offical documentation:
raise
raise( string )
raise( exception [, string [, array ] ] )
不带参数,在$!
中引发异常,如果$!
为nil,则引发RuntimeError
。使用单个 String
参数,它会引发 RuntimeError
并将字符串作为消息。否则,第一个参数应该是Exception
类的名称(或在发送异常时返回Exception
的对象)。可选的第二个参数设置与异常关联的消息,第三个参数是回调信息数组。异常被 begin...end
块的救援子句捕获。
raise "Failed to create socket"
raise ArgumentError, "No parameters", caller
【讨论】:
【参考方案2】:从技术上讲,第一个引发 RuntimeError 并将消息设置为 "foo"
,第二个引发一个异常并将消息设置为 "foo"
。
实际上,您想要使用前者的时间和想要使用后者的时间之间存在显着差异。
简单地说,您可能需要RuntimeError
而不是Exception
。没有参数的救援块将捕获RuntimeErrors
,但不会捕获Exception
s。因此,如果您在代码中提出Exception
,此代码将无法捕获它:
begin
rescue
end
为了赶上Exception
,您必须这样做:
begin
rescue Exception
end
这意味着在某种意义上,Exception
是一个比RuntimeError
更“糟糕”的错误,因为您必须做更多的工作才能从中恢复。
所以你想要什么取决于你的项目如何处理它的错误。例如,在我们的守护进程中,主循环有一个空白救援,它将捕获RuntimeErrors
,报告它们,然后继续。但在一两种情况下,我们希望守护进程真正死于错误,在这种情况下,我们会引发Exception
,它会直接通过我们的“正常错误处理代码”并退出。
同样,如果您正在编写库代码,您可能需要RuntimeError
,而不是Exception
,因为如果它引发空白rescue
块无法捕获的错误,您的库用户会感到惊讶,他们需要一点时间才能意识到原因。
最后,我应该说RuntimeError
是StandardError
类的子类,而实际的规则是虽然你可以raise
any 类型的对象,但空白的@默认情况下,987654341@ 只会捕获从StandardError
继承的任何内容。其他一切都必须具体。
【讨论】:
非常有用,谢谢。一些事情:[1] 最后一段是最有启发性的,让我在 irb 发现一些你没有提到的东西:RuntimeError < StandardError < Exception
[2] 因此,第二个代码块将捕获异常和 RuntimeError [3] 有趣/奇怪的是,“裸”引发和救援恰好与特定异常 [4] 一起工作,也许经验法则是将 RuntimeError 引发到客户端代码,但引发和救援自己的代码在自己的代码中自定义异常?
[1, 2] 是的。 [3] 不确定... [4] 当我最专业地编写代码时,我倾向于创建从StandardError
继承的自定义错误类型。它不必比像class MissingArgumentsError < StandardError; end
这样的几行更复杂。
信息量很大,但是如果在编写libraray时首选运行时错误,那么在什么情况下你会想要抛出异常而不是运行时错误?以上是关于`raise "foo"` 和 `raise Exception.new("foo")` 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章
如何解决 raise ValueError("columns must have matching element counts") ValueError: columns mus
jpype测试报错,找不到类raise _RUNTIMEEXCEPTION.PYEXC("Class %s not found" % name)
函数 foo(param) alert("foo 调用"); 和 $scope.foo = function(param)alert("foo");;
python pip安装 mysqlclient 报错 raise EnvironmentError("%s not found" % (_mysql_config_path,))
raise ValueError("Unknown label type: %s" % repr(ys)) ValueError: Unknown label type: (arr