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
?
解决方法
Some languages call for unwinding the stack as this search progresses. That is,if function
f
,containing a handlerH
for exceptionE
,calls functiong
,which in turn calls functionh
,and an exceptionE
occurs inh
,then functionsh
andg
may be terminated,andH
inf
will handleE
.
而Swift错误不会解除堆栈查找处理程序的问题.它只是返回,并期望调用者处理抛出的错误.事实上,你引用goes on to say之后的句子:
As such,the performance characteristics of a
throw
statement are comparable to those of areturn
statement.
所以,使用第一个例子,其中f调用g来调用h,在Swift中,如果你想要f来捕获由h抛出的错误,那么:
> h必须明确标记为抛出错误;
> g必须明确地尝试调用h;
> g也必须标记它也会引发错误;和
> f必须明确地尝试调用g.
简而言之,虽然其他一些语言在查找异常处理程序的过程中提供堆栈展开,但在Swift错误处理中,您必须显式捕获您尝试的函数抛出的错误,或者将其指定为抛出的函数,以便尝试调用失败将被抛回调用者.在Swift中没有自动展开堆栈.
所有这些都与是否发生解除分配无关.正如您所见,是的,Swift中的抛出与返回非常相似,可以释放那些局部变量.
值得注意的是,并非所有涉及堆栈展开的异常处理都会进行重新分配.通常它确实如此(因为当我们处理异常时我们希望它清理),但是例如,“当发生未处理的异常时,GNU C unwinder不会调用对象析构函数.原因是为了提高可调试性. “ (从Exception Handling in LLVM开始.)显然,这仅适用于调试环境中的未处理异常,但它说明了展开堆栈并不一定意味着对象被解除分配的问题.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。