exception - "errors/exceptions"和 "throw/catch"之间的区别?

标签 exception error-handling 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!"

但是这种 throw 和捕获与传递给 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!

(注意:您可以 use pre-made errors apparently,例如 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 在返回值和抛出值之间也没有类似的区别。但是有一个工具可以通过“命名 throw ”来解决这个问题:
>> 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

那么现在问题来了:
  • 这种分离有实际值(value)吗?如何决定是使用 THROW 和 CATCH 还是错误的 DO 并使用 TRY/EXCEPT 处理它?
  • 这种区别在其他语言中是否有先例,/EXCEPT 是否更好地命名为/ON-ERROR 或其他什么?
  • 为什么说"no catch for throw: make error! 2"而不是更多信息?什么是make error! 2 ?
  • 最佳答案

    "Is there a practical value to this separation? How does one decide whether to use THROW and CATCH or a DO of an error and handle it with TRY/EXCEPT?"



    正如其他答案中所指出的那样,THROW 和 CATCH 形成了一个展开结构(非本地导出),它本身与控制流有关,不一定与错误处理有关。 THROW 和 CATCH 首先是影响控制流的直接方法,并且是其他自定义控制流构造的基本构建块。

    因此,THROW 和 CATCH 当然也可以用于构建类似“异常处理”的错误系统,就像在许多当代主流语言中看到的那样,因为那些“异常处理”系统是非本地控制流的一个实例。

    Rebol 的 error!另一方面是信号和传播评估错误的主要方法。

    所以一般来说,决定很容易做出:如果你想引起错误,使用 error! .如果要影响控制流以可控地展开,请使用 THROW/CATCH。

    关于术语的另外两点说明:
  • 关于 Rebol 错误的讨论 has become more careful使用“cause an error”作为短语而不是“throw an error”,以避免混淆。
  • 同样,调用 THROW/CATCH “Rebol 的异常处理”(正如@HostileFork 在一个评论中提到的)的引用需要重新设计。

  • "Does this distinction have precedent in other languages"



    是的,求值错误和非本地退出的区别在其他语言中已有先例,尤其是 Lisp 家族。一些快速引用:
  • Common Lisps catch throw 对比 condition signaling
  • Emacs Lisp 的 catch and throw 对比 error signaling
  • 迪伦的 block 对比 condition system

  • "Why does it say "no catch for throw: make error! 2" instead of something more informative? What is the make error! 2?"



    那是一个错误。 (很好的捕获!)我会说错误消息的核心(“no catch for throw”)已经提供了相当多的信息,但是 make error! 2是一个错误(它应该在这里显示抛出的值。)

    "would /EXCEPT be better named /ON-ERROR or something?"



    重命名 /EXCEPT值得商榷。因此,我会说这是一个不适合 SO Q&A 的讨论,最好留给其他论坛。

    关于exception - "errors/exceptions"和 "throw/catch"之间的区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24412153/

    相关文章:

    swift - “ fatal error :在展开可选值时意外发现nil”是什么意思?

    vb.net - 哪种形式导致了我的异常(exception)?

    mongodb - MongoDB 3.0.1 mongodump错误

    红色的 REBOL 方法

    asynchronous - 同步读/写端口时避免递归?

    exception - 单声道-System.TypeLoadException : Could not load types

    javascript通行证

    javascript - 捕获除解析/拒绝 promise 以外的Http错误

    r - Excel IFERROR 的 R 等效项是什么?

    REBOL 3 - 在哪里可以访问用户定义的命名空间词?