如何在Swift中向堆栈跟踪传递错误
在java中,如果一个方法抛出错误,则调用它的方法可以将其传递给下一个方法。
public void foo() throws Exception { throw new Exception(); } public void bar() throws Exception { foo(); } public static void main(String args[]) { try { bar(); } catch(Exception e) { System.out.println("Error"); } }
我正在写一个快速的应用程序,并希望做同样的事情。 这可能吗? 如果不可能有什么其他可能的解决方案? 我调用此调用的原始函数具有此结构。
func convert(name: String) throws -> String { }
参考Swift – error handling文档 ,您应该:
1-通过声明符合错误协议的 枚举来创建自定义错误类型:
enum CustomError: Error { case error01 }
2-将 foo()
声明为throwable函数:
func foo() throws { throw CustomError.error01 }
3-将 bar()
声明为throwable函数:
func bar() throws { try foo() }
请注意,尽管bar()
是throwable( throws
),但它不包含throw
,为什么? 因为它调用foo()
(它也是一个抛出错误的函数), try
意味着抛出将 – 隐式 – 转到foo()
。
为了更清楚:
4-实现test()
函数(Do-Catch):
func test() { do { try bar() } catch { print("\(error) has been caught!") } }
5-调用test()
函数:
test() // error01 has been caught!
如您所见, bar()
自动抛出错误,这是指foo()
函数错误抛出。
Swift函数可以调用throwing函数并将错误传递给调用者,但是
- 函数本身必须用
throws
标记,并且 - 必须通过
try
调用throw函数。
例:
func foo() throws { print("in foo") throw NSError(domain: "mydomain", code: 123, userInfo: nil) } func bar() throws -> String { print("in bar") try foo() return "bar" } do { let result = try bar() print("result:", result) } catch { print(error.localizedDescription) }
输出:
在酒吧 在foo 操作无法完成。 (mydomain错误123.)
如果try foo()
失败,则bar()
立即返回,将foo()
抛出的错误传播给其调用者。 换句话说, try foo()
内部的抛出函数相当于
do { try foo() } catch let error { throw error }
Swift处理错误的传播,并且没有exception机制。 在Swift中,被调用的函数可以将遇到的错误传递给调用它的上下文。 但是,尽管使用了关键字throw
但实际上并没有抛出exception。 它只是通过一个与函数返回值不同的通道传递错误。
我想那个例程,调用者,然后可以将它调用的函数中的错误解释为错误本身,并将相关的错误传递给它的调用者,但一般来说Swift中没有机制允许你跳过堆栈遇到错误情况时的帧。
在Swift中,错误由符合Error协议的类型的值表示。 此空协议表示类型可用于error handling。
在Swift中, 只有抛出函数才能传播错误 。 必须在函数内部处理在非throwing函数内抛出的任何错误。
抛出错误可以指示发生了意外情况,并且正常的执行流程无法继续。 您使用throw语句抛出错误。
有四种方法可以处理Swift中的错误。
- 您可以将错误从函数传播到调用该函数的代码,
- 使用do-catch语句处理错误,
- 将错误作为可选值处理,或
-
断言不会发生错误。
与许多语言中的exception处理不同 – 包括Swift中的Objective-Cerror handling不涉及展开调用堆栈
虽然Swift错误的使用方式与Java的Checkedexception类似,但它们并不完全相同。
Swift中的error handling类似于使用try,catch和throw关键字在其他语言中的exception处理。 与许多语言中的exception处理不同 – 包括Swift中的Objective-Cerror handling不涉及展开调用堆栈,这个过程可能在计算上很昂贵。 因此,throw语句的性能特征与return语句的性能特征相当 。
请参阅Swifterror handling