我对Rebol中的错误处理感到有点困惑.它有THROW和CATCH结构:
>> repeat x 10 [if x = 9 [throw "Nine!"]] ** Throw error: no catch for throw: make error! 2 >> catch [repeat x 10 [if x = 9 [throw "Nine!"]]] == "Nine!"
但是这个抛出和捕获与传递给TRY上的/ EXCEPT细化的处理程序无关:
>> try/except [throw "Nine!"] [print "Exception handled!"] ** Throw error: no catch for throw: make error! 2
这对于Rebol的错误类型非常具体:
>> try/except [print 1 / 0] [print "Error handled!"] Error handled!
如果你想要,你可以触发自己的错误,但不像其他语言那样使用THROW.抛出错误只会导致抱怨没有被抓住,就像任何其他价值类型一样:
>> try/except [throw make error! "Error string"] [print "Error handled!"] ** Throw error: no catch for throw: make error! 2
你必须让他们让评估者尝试执行类型错误的东西!导致它认为是"例外":
>> try/except [do make error! "Error string"] [print "Error handled!"] Error handled!
(注意:您可以使用明显的错误,例如cause-error 'Script 'invalid-type function!
- 请参阅system/catalog/errors
更多信息.)
退出/ EXCEPT细化将使您收到任何错误值.但是,这似乎无法区分是否调用了错误:
>> probe try [do make error! "Some error"] make error! [ code: 800 type: 'User id: 'message arg1: "some error" arg2: none arg3: none near: none where: none ] ** User error: "Some error" >> probe try [make error! "Some error"] make error! [ code: 800 type: 'User id: 'message arg1: "Some error" arg2: none arg3: none near: none where: none ] ** User error: "Some error"
似乎CATCH在返回值和抛出值之间没有类似的区别.但是有一个工具可以通过"命名投掷"解决这个问题:
>> code: [repeat x 10 [if x = 9 [throw/name "Nine!" 'number]]] >> catch/name [do code] 'number == "Nine!" >> catch/name [do code] 'somethingelse ** Throw error: no catch for throw: make error! 2
所以现在问题:
这种分离有实际价值吗?如何决定是使用THROW和CATCH还是错误的DO并使用TRY/EXCEPT处理它?
这种区别是否在其他语言中有先例,并且/除了更好的命名/ ON-ERROR之外还有什么?
为什么要说"no catch for throw: make error! 2"
而不是更具信息量的东西呢?什么是make error! 2
?
earl.. 5
"这种分离是否具有实际价值?如何决定是使用THROW和CATCH还是错误的DO并使用TRY/EXCEPT处理它?"
正如在其他答案中已经指出的那样,THROW和CATCH形成一个展开构造(非本地出口),其本身与控制流有关,并且不一定与错误处理有任何关系.THROW和CATCH首先是影响控制流的直接方法,并且是其他自定义控制流构造的相当基础的构建块.
因此,THROW和CATCH当然也可用于构建像许多当代主流语言中所见的"异常处理"类错误系统,因为那些"异常处理"系统是非本地控制流的一个实例.
error!
另一方面,Rebol 是发出评估错误信号和传播的主要方法.
所以一般来说,这个决定很容易做出:如果你想引起错误,请使用error!
.如果您想影响控制流以可控地展开,请使用THROW/CATCH.
关于术语的另外两个评论:
关于Rebol错误的讨论变得更加谨慎,使用" 导致错误"作为短语而不是"抛出错误",以避免混淆.
类似地,调用THROW/CATCH"Rebol的异常处理"的引用(如@HostileFork在一条评论中暗示的那样)需要重新编写.
"这种区别在其他语言中是先例吗?"
是的,评估错误和非本地退出之间的区别在其他语言中是先例,尤其是Lisp家族.一些快速参考:
Common Lisps catch
和throw
vs 条件信令
Emacs Lisp catch
和throw
vs 错误信号
迪伦block
与条件系统
"为什么它说"没有抓住投掷:犯错误!2"而不是更具信息性的东西?什么是制造错误!2?"
那是一个错误.(好抓!)我会说错误消息的核心("没有抓住投掷")已经提供了相当丰富的信息,但这make error! 2
是一个错误(它应该在这里显示抛出的值.)
"将/更好地命名/ ON-ERROR或其他什么?"
重命名/EXCEPT
是值得商榷的.因此,我认为这是一个不适合SO Q&A的讨论,最好留给其他论坛.
"这种分离是否具有实际价值?如何决定是使用THROW和CATCH还是错误的DO并使用TRY/EXCEPT处理它?"
正如在其他答案中已经指出的那样,THROW和CATCH形成一个展开构造(非本地出口),其本身与控制流有关,并且不一定与错误处理有任何关系.THROW和CATCH首先是影响控制流的直接方法,并且是其他自定义控制流构造的相当基础的构建块.
因此,THROW和CATCH当然也可用于构建像许多当代主流语言中所见的"异常处理"类错误系统,因为那些"异常处理"系统是非本地控制流的一个实例.
error!
另一方面,Rebol 是发出评估错误信号和传播的主要方法.
所以一般来说,这个决定很容易做出:如果你想引起错误,请使用error!
.如果您想影响控制流以可控地展开,请使用THROW/CATCH.
关于术语的另外两个评论:
关于Rebol错误的讨论变得更加谨慎,使用" 导致错误"作为短语而不是"抛出错误",以避免混淆.
类似地,调用THROW/CATCH"Rebol的异常处理"的引用(如@HostileFork在一条评论中暗示的那样)需要重新编写.
"这种区别在其他语言中是先例吗?"
是的,评估错误和非本地退出之间的区别在其他语言中是先例,尤其是Lisp家族.一些快速参考:
Common Lisps catch
和throw
vs 条件信令
Emacs Lisp catch
和throw
vs 错误信号
迪伦block
与条件系统
"为什么它说"没有抓住投掷:犯错误!2"而不是更具信息性的东西?什么是制造错误!2?"
那是一个错误.(好抓!)我会说错误消息的核心("没有抓住投掷")已经提供了相当丰富的信息,但这make error! 2
是一个错误(它应该在这里显示抛出的值.)
"将/更好地命名/ ON-ERROR或其他什么?"
重命名/EXCEPT
是值得商榷的.因此,我认为这是一个不适合SO Q&A的讨论,最好留给其他论坛.