加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Swift中的错误处理不涉及堆栈展开.这是什么意思?

发布时间:2020-12-14 04:36:17 所属栏目:百科 来源:网络整理
导读:根据文件, error handling in Swift does not involve unwinding the call stack,a process that can be computationally expensive 我想知道它是什么意思?我一直认为堆栈展开是一个在异常情况下(就C而言)正确调用析构函数的过程. 所以我决定对情况进行建模
根据文件,

error handling in Swift does not involve unwinding the call stack,a
process that can be computationally expensive

我想知道它是什么意思?我一直认为堆栈展开是一个在异常情况下(就C而言)正确调用析构函数的过程.

所以我决定对情况进行建模:

class A {
    init() {
        print("Inited")
    }
    deinit {
        print("Deinited")
    }
}

func f() throws {
    let a = A()
    throw MyError.e
}

输出是:

Inited
Deinited

所以“析构函数”被调用 – 这意味着(在我的理解中)堆栈展开在Swift中起作用.

任何人都可以解释为什么文档说它是

not involved

解决方法

堆栈展开只是导航堆栈中寻找处理程序的过程.维基百科 summarizes it as follows:

Some languages call for unwinding the stack as this search progresses. That is,if function f,containing a handler H for exception E,calls function g,which in turn calls function h,and an exception E occurs in h,then functions h and g may be terminated,and H in f will handle E.

而Swift错误不会解除堆栈查找处理程序的问题.它只是返回,并期望调用者处理抛出的错误.事实上,你引用goes on to say之后的句子:

As such,the performance characteristics of a throw statement are comparable to those of a return statement.

所以,使用第一个例子,其中f调用g来调用h,在Swift中,如果你想要f来捕获由h抛出的错误,那么:

> h必须明确标记为抛出错误;
> g必须明确地尝试调用h;
> g也必须标记它也会引发错误;和
> f必须明确地尝试调用g.

简而言之,虽然其他一些语言在查找异常处理程序的过程中提供堆栈展开,但在Swift错误处理中,您必须显式捕获您尝试的函数抛出的错误,或者将其指定为抛出的函数,以便尝试调用失败将被抛回调用者.在Swift中没有自动展开堆栈.

所有这些都与是否发生解除分配无关.正如您所见,是的,Swift中的抛出与返回非常相似,可以释放那些局部变量.

值得注意的是,并非所有涉及堆栈展开的异常处理都会进行重新分配.通常它确实如此(因为当我们处理异常时我们希望它清理),但是例如,“当发生未处理的异常时,GNU C unwinder不会调用对象析构函数.原因是为了提高可调试性. “ (从Exception Handling in LLVM开始.)显然,这仅适用于调试环境中的未处理异常,但它说明了展开堆栈并不一定意味着对象被解除分配的问题.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读