我对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处理它?
这种区分在其他语言中是否有先例,/EXCEPT是否更好地命名为/ON-ERROR或其他名称?
为什么它说“没有捕获throw:make error!2”而不是更多信息?“make error! 2”是什么意思?