"错误/异常"和"抛出/捕获"之间的区别?

 终渐疯分_501 发布于 2023-01-07 17:13

我对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 catchthrowvs 条件信令

Emacs Lisp catchthrow vs 错误信号

迪伦block与条件系统

"为什么它说"没有抓住投掷:犯错误!2"而不是更具信息性的东西?什么是制造错误!2?"

那是一个错误.(好抓!)我会说错误消息的核心("没有抓住投掷")已经提供了相当丰富的信息,但这make error! 2是一个错误(它应该在这里显示抛出的值.)

"将/更好地命名/ ON-ERROR或其他什么?"

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

1 个回答
  • "这种分离是否具有实际价值?如何决定是使用THROW和CATCH还是错误的DO并使用TRY/EXCEPT处理它?"

    正如在其他答案中已经指出的那样,THROW和CATCH形成一个展开构造(非本地出口),其本身与控制流有关,并且不一定与错误处理有任何关系.THROW和CATCH首先是影响控制流的直接方法,并且是其他自定义控制流构造的相当基础的构建块.

    因此,THROW和CATCH当然也可用于构建像许多当代主流语言中所见的"异常处理"类错误系统,因为那些"异常处理"系统是非本地控制流的一个实例.

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

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

    关于术语的另外两个评论:

    关于Rebol错误的讨论变得更加谨慎,使用" 导致错误"作为短语而不是"抛出错误",以避免混淆.

    类似地,调用THROW/CATCH"Rebol的异常处理"的引用(如@HostileFork在一条评论中暗示的那样)需要重新编写.

    "这种区别在其他语言中是先例吗?"

    是的,评估错误和非本地退出之间的区别在其他语言中是先例,尤其是Lisp家族.一些快速参考:

    Common Lisps catchthrowvs 条件信令

    Emacs Lisp catchthrow vs 错误信号

    迪伦block与条件系统

    "为什么它说"没有抓住投掷:犯错误!2"而不是更具信息性的东西?什么是制造错误!2?"

    那是一个错误.(好抓!)我会说错误消息的核心("没有抓住投掷")已经提供了相当丰富的信息,但这make error! 2是一个错误(它应该在这里显示抛出的值.)

    "将/更好地命名/ ON-ERROR或其他什么?"

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

    2023-01-07 17:15 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有