代码之家  ›  专栏  ›  技术社区  ›  alsor.net

为什么许多语言将异常对象视为头等公民?

  •  2
  • alsor.net  · 技术社区  · 15 年前

    当我们得到一个实际上是例外的对象时,我们可以用它们来处理我们语言中的序数对象。我们可以将它们作为参数传递,也可以将它们存储在某个集合中,最糟糕的是,我们可以将它们作为方法的结果返回!

    所以有可能有人写这样的臭代码:

    public Exception doSomethingCritical()
    {
        Exception error = null;
    
        try
        {
            ...
        }
        catch (Exception e)
        {
            // maybe at least here is the logging of the error if we are lucky
            error = e;
        }
        return error;
    }
    

    所以问题是,为什么异常对象的概念在许多OO语言中是一流的公民?如果语言中只允许例外对象(如throw)使用有限的构造,也许更好。

    7 回复  |  直到 15 年前
        1
  •  1
  •   Stefano Borini    15 年前

    我的意见。

    我认为您混淆了两个不同的东西:异常和异常抛出。

    异常抛出是一个带外过程,允许您通过一个优先的横向通道抛出一个对象。可以通过异常捕获机制截取和处理此对象。

    异常只是一个可以(优先)通过异常抛出带外通道抛出的对象。当然,这个通道可以具有被抛出对象的接口的必要条件,以及由异常类接口满足的必要条件。

    你从另一个角度看待这个问题。事实上,你可以做恐怖的事情,但是例外对象没有什么特别的,除了作为被抛出带外通道的首选对象。

        2
  •  6
  •   Ryan Brunner    15 年前

    将异常视为一种特殊情况,并且只允许有限的功能(除了异常)的问题在于,最终每个好的程序都需要做些什么 某物 除了异常,无论是全局错误处理程序还是适当处理异常的有限项。一等公民例外,有很多好处,例如:

    • 允许对异常进行子类化。这对于异常处理是无价的,因为处理异常的代码可以缩小它们的范围,只处理它们知道如何处理的异常。我想说的是,任何只捕获“异常”的非全局异常处理例程都可能做错了。
    • 传递数据以及异常。如果您在catch逻辑中只知道发生了异常,那么异常就不是很有用了。对于某些异常类型,堆栈跟踪、消息甚至自定义数据对于识别和解决导致异常的问题都是非常宝贵的。
    • 创建使用OOP本身的错误处理例程。如果不能将异常作为对象传递,那么您就不能拥有一个处理异常的库——好吧,至少不是一个写得好的库。

    除此之外,没有办法像上面提到的那样防止错误的异常处理。即使一个例外不是一等公民,也没有办法阻止开发人员吃任何和所有的例外,并继续他们的快乐方式(至少,不从根本上打破我们对例外的看法)

        3
  •  2
  •   pjc50    15 年前

    我从来没有见过你用过的那个例子。我不明白不允许人们返回异常会对概念上较差的代码产生什么样的影响-比较

    public int doSomethingCritical()
    {
        int error = 0;
    
        try
        {
            ...
        }
        catch (Exception e)
        {
            // maybe at least here is the logging of the error if we are lucky
            error = E_SOMETHINGBAD;
        }
        return error;
    }
    

    然而,如果您创建了一种新的“东西”来用于与对象不同的异常,则存在设计和学习开销方面的缺点。

        4
  •  1
  •   Chad    15 年前

    如果模块不是第一类公民,您如何能够从基本异常类继承并为模块派生自己的异常类?

        5
  •  1
  •   Christian Hayter    15 年前

    我不明白为什么我不应该被允许作为普通方法参数传递和返回异常。如果我正在编写一个异常处理库呢?如果我正在编写一个单元测试断言来比较异常呢?

        6
  •  0
  •   kdgregory    15 年前

    因为那样生活容易多了。除其他外,它意味着异常对象可以包含程序可以用来纠正异常情况的信息(可能需要人工干预)。

    阿本德就是60年代。

        7
  •  0
  •   ennuikiller    15 年前

    我不确定您给出的示例是否足以证明不将异常作为对象。毕竟,你可以在编程时做各种“难闻”或“不好”的事情。然而,这正是我们想要优秀程序员的原因。只是因为我可以像这样做:

    def get_total
       return nil
    end
    

    当然,这并不意味着我不应该允许将nil作为对象的实例!

    推荐文章