Hos*_*ork 4 error-handling exception rebol rebol3
我对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!"
Run Code Online (Sandbox Code Playgroud)
但是这个抛出和捕获与传递给TRY上的/ EXCEPT细化的处理程序无关:
>> try/except [throw "Nine!"] [print "Exception handled!"]
** Throw error: no catch for throw: make error! 2
Run Code Online (Sandbox Code Playgroud)
这对于Rebol的错误类型非常具体:
>> try/except [print 1 / 0] [print "Error handled!"]
Error handled!
Run Code Online (Sandbox Code Playgroud)
如果你想要,你可以触发自己的错误,但不像其他语言那样使用THROW.抛出错误只会导致抱怨没有被抓住,就像任何其他价值类型一样:
>> try/except [throw make error! "Error string"] [print "Error handled!"]
** Throw error: no catch for throw: make error! 2
Run Code Online (Sandbox Code Playgroud)
你必须让他们让评估者尝试执行类型错误的东西!导致它认为是"例外":
>> try/except [do make error! "Error string"] [print "Error handled!"]
Error handled!
Run Code Online (Sandbox Code Playgroud)
(注意:您可以使用明显的错误,例如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"
Run Code Online (Sandbox Code Playgroud)
似乎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
Run Code Online (Sandbox Code Playgroud)
所以现在问题:
这种分离有实际价值吗?如何决定是使用THROW和CATCH还是错误的DO并使用TRY/EXCEPT处理它?
这种区别是否在其他语言中有先例,并且/除了更好的命名/ ON-ERROR之外还有什么?
为什么要说"no catch for throw: make error! 2"
而不是更具信息量的东西呢?什么是make error! 2
?
"这种分离是否具有实际价值?如何决定是使用THROW和CATCH还是错误的DO并使用TRY/EXCEPT处理它?"
正如在其他答案中已经指出的那样,THROW和CATCH形成一个展开构造(非本地出口),其本身与控制流有关,并且不一定与错误处理有任何关系.THROW和CATCH首先是影响控制流的直接方法,并且是其他自定义控制流构造的相当基础的构建块.
因此,THROW和CATCH当然也可用于构建像许多当代主流语言中所见的"异常处理"类错误系统,因为那些"异常处理"系统是非本地控制流的一个实例.
error!
另一方面,Rebol 是发出评估错误信号和传播的主要方法.
所以一般来说,这个决定很容易做出:如果你想引起错误,请使用error!
.如果您想影响控制流以可控地展开,请使用THROW/CATCH.
关于术语的另外两个评论:
"这种区别在其他语言中是先例吗?"
是的,评估错误和非本地退出之间的区别在其他语言中是先例,尤其是Lisp家族.一些快速参考:
"为什么它说"没有抓住投掷:犯错误!2"而不是更具信息性的东西?什么是制造错误!2?"
那是一个错误.(好抓!)我会说错误消息的核心("没有抓住投掷")已经提供了相当丰富的信息,但这make error! 2
是一个错误(它应该在这里显示抛出的值.)
"将/更好地命名/ ON-ERROR或其他什么?"
重命名/EXCEPT
是值得商榷的.因此,我认为这是一个不适合SO Q&A的讨论,最好留给其他论坛.