mirror of
https://github.com/NohamR/knowledge-kit.git
synced 2026-05-24 20:00:37 +00:00
137 lines
3.1 KiB
Markdown
137 lines
3.1 KiB
Markdown
# Swift 错误处理
|
||
|
||
```swift
|
||
enum SomeError: Error {
|
||
case illegalArg(String)
|
||
case outOfBounds(Int, Int)
|
||
case outOfMemory
|
||
}
|
||
|
||
func divide(_ num1: Int, _ num2: Int) throws -> Int {
|
||
if num2 == 0 {
|
||
throw SomeError.illegalArg("分母不能为0")
|
||
}
|
||
return num1/num2
|
||
}
|
||
|
||
func testErrorCapture() {
|
||
print("1")
|
||
do {
|
||
print("2")
|
||
print(try divide(20, 0))
|
||
print("3")
|
||
} catch let SomeError.illegalArg(msg) {
|
||
print("参数异常:", msg)
|
||
} catch let SomeError.outOfBounds(size, index) {
|
||
print("下标越界: size = \(size), index = \(index)")
|
||
} catch SomeError.outOfMemory {
|
||
print("内存溢出")
|
||
} catch {
|
||
print("其他异常")
|
||
}
|
||
print("4")
|
||
}
|
||
testErrorCapture()
|
||
// console
|
||
1
|
||
2
|
||
参数异常: 分母不能为0
|
||
4
|
||
```
|
||
|
||
如果 `try divide(20, 0)` 则输出: 1 、2、参数异常: 分母不能为0、4
|
||
|
||
如果 `try divide(20, 2)` 则输出: 1 、2、10、3、4
|
||
|
||
说明:如果 do 抛出异常,则作用域内的后续的其他代码都不会被执行
|
||
|
||
|
||
|
||
## Error 处理方式
|
||
|
||
- 通过 do-catch 捕捉 Error
|
||
|
||
- 不捕捉 Error,在当前函数增加 throws 声明,Error 继续向上层调用函数抛
|
||
|
||
```swift
|
||
func divide(_ num1: Int, _ num2: Int) throws -> Int {
|
||
if num2 == 0 {
|
||
throw SomeError.illegalArg("分母不能为0")
|
||
}
|
||
return num1/num2
|
||
}
|
||
|
||
func safeDivide(_ num1: Int, _ num2: Int) -> Int {
|
||
var result:Int = 0
|
||
do {
|
||
result = try divide(num1, num2)
|
||
} catch let SomeError.illegalArg(msg) {
|
||
print("参数异常:", msg)
|
||
} catch let SomeError.outOfBounds(size, index) {
|
||
print("下标越界: size = \(size), index = \(index)")
|
||
} catch SomeError.outOfMemory {
|
||
print("内存溢出")
|
||
} catch {
|
||
print("其他异常")
|
||
}
|
||
return result
|
||
}
|
||
|
||
print("1")
|
||
print(safeDivide(8, 2))
|
||
print("3")
|
||
// console
|
||
1
|
||
4
|
||
3
|
||
```
|
||
|
||
- 如果有些错误不需要向上抛,可以用 `try?` ` try!` 调用可能会抛出 Error 的函数,这样就不需要去处理 Error
|
||
|
||
```swift
|
||
func testIgnoreError () {
|
||
print("1")
|
||
print(try? divide(10, 0))
|
||
print("2")
|
||
}
|
||
testIgnoreError()
|
||
// console
|
||
1
|
||
nil
|
||
2
|
||
```
|
||
|
||
|
||
|
||
## rethrows
|
||
|
||
如果一个函数本身不会抛出错误,但某个参数是闭包,且闭包抛出错误,那么函数需要用 `rethrows` 向上抛出错误
|
||
|
||
```swift
|
||
func exec(_ fn: (Int, Int) throws -> Int, _ num1: Int, _ num2: Int) rethrows {
|
||
print(try fn(num1, num2))
|
||
}
|
||
|
||
func testCaptureClouserError () {
|
||
do {
|
||
try exec(divide, 20, 0)
|
||
} catch let error {
|
||
switch error {
|
||
case let SomeError.illegalArgs(msg):
|
||
print("参数异常:", msg)
|
||
break
|
||
case let SomeError.outOfBounds(size, index):
|
||
print("下标越界: size = \(size), index = \(index)")
|
||
break
|
||
case SomeError.outOfMemory :
|
||
print("内存溢出")
|
||
break
|
||
default:
|
||
print("其他异常")
|
||
}
|
||
}
|
||
}
|
||
testCaptureClouserError() // 参数异常: 分母不能为0
|
||
```
|
||
|